gofront 1.7.0 → 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.
Files changed (128) hide show
  1. package/README.md +13 -13
  2. package/package.json +8 -37
  3. package/src/backend/js/expressions.js +1341 -148
  4. package/src/backend/js/fmt-runtime.js +573 -0
  5. package/src/backend/js/index.js +375 -57
  6. package/src/backend/js/runtime.js +1460 -133
  7. package/src/backend/js/statements.js +900 -86
  8. package/src/backend/js/stdlib/bits.js +87 -14
  9. package/src/backend/js/stdlib/builder.js +41 -6
  10. package/src/backend/js/stdlib/bytes.js +253 -7
  11. package/src/backend/js/stdlib/errors.js +2 -1
  12. package/src/backend/js/stdlib/fmt.js +349 -10
  13. package/src/backend/js/stdlib/index.js +8 -3
  14. package/src/backend/js/stdlib/json.js +247 -52
  15. package/src/backend/js/stdlib/maps.js +0 -8
  16. package/src/backend/js/stdlib/math.js +17 -1
  17. package/src/backend/js/stdlib/simd.js +10 -0
  18. package/src/backend/js/stdlib/slices.js +36 -6
  19. package/src/backend/js/stdlib/strconv.js +10 -5
  20. package/src/backend/js/stdlib/strings.js +83 -4
  21. package/src/backend/js/stdlib/testing.js +7 -0
  22. package/src/backend/js/stdlib/time.js +79 -55
  23. package/src/backend/js/stdlib/unicode.js +1 -1
  24. package/src/backend/js/stdlib/utf8.js +1 -1
  25. package/src/backend/js/templ.js +38 -76
  26. package/src/backend/js/type-info.js +272 -0
  27. package/src/backend/shared/fmt-types.js +188 -0
  28. package/src/backend/wasm/boundary.js +436 -80
  29. package/src/backend/wasm/emit-builtins.js +303 -13
  30. package/src/backend/wasm/emit-exprs.js +1397 -203
  31. package/src/backend/wasm/emit-maps.js +61 -13
  32. package/src/backend/wasm/emit-stmts.js +1359 -164
  33. package/src/backend/wasm/emit.js +512 -77
  34. package/src/backend/wasm/encode.js +43 -13
  35. package/src/backend/wasm/globals.js +452 -0
  36. package/src/backend/wasm/index.js +194 -2489
  37. package/src/backend/wasm/method-expr.js +381 -0
  38. package/src/backend/wasm/module-emitter.js +2240 -0
  39. package/src/backend/wasm/monomorph.js +62 -4
  40. package/src/backend/wasm/prescan.js +397 -0
  41. package/src/backend/wasm/stdlib/bytes.js +1804 -127
  42. package/src/backend/wasm/stdlib/core.js +1574 -199
  43. package/src/backend/wasm/stdlib/index.js +0 -5
  44. package/src/backend/wasm/stdlib/io.js +1567 -150
  45. package/src/backend/wasm/stdlib/packages.js +2 -0
  46. package/src/backend/wasm/stdlib/simd.js +293 -28
  47. package/src/backend/wasm/stdlib/time.js +1041 -12
  48. package/src/backend/wasm/types.js +200 -15
  49. package/src/backend/wasm/variadic.js +93 -0
  50. package/src/backend/wasm/wat.js +47 -20
  51. package/src/{cli-core.js → cli/cli-core.js} +236 -10
  52. package/src/{test-runner.js → cli/test-runner.js} +332 -39
  53. package/src/{vendor.js → cli/vendor.js} +3 -4
  54. package/src/compiler.js +107 -269
  55. package/src/index.js +15 -169
  56. package/src/{lexer.js → lexer/lexer.js} +102 -55
  57. package/src/{tokens.js → lexer/tokens.js} +1 -0
  58. package/src/link/sourcemap.js +97 -0
  59. package/src/link/stdlib.js +515 -0
  60. package/src/link/wasm.js +294 -0
  61. package/src/lower/bounds.js +394 -0
  62. package/src/lower/boxing.js +1 -1
  63. package/src/lower/captures.js +176 -32
  64. package/src/lower/index.js +26 -18
  65. package/src/lower/json-codecs.js +1398 -0
  66. package/src/lower/ownership.js +22 -1
  67. package/src/lower/range.js +86 -1
  68. package/src/lower/reachability.js +132 -0
  69. package/src/parser/declarations.js +58 -13
  70. package/src/parser/expressions.js +29 -7
  71. package/src/parser/index.js +2 -1
  72. package/src/parser/statements.js +37 -22
  73. package/src/{templ-parser.js → parser/templ.js} +138 -15
  74. package/src/parser/types.js +69 -9
  75. package/src/resolver.js +22 -1
  76. package/src/typechecker/assignability.js +176 -17
  77. package/src/typechecker/const-fold.js +356 -0
  78. package/src/typechecker/constants.js +256 -0
  79. package/src/typechecker/expressions.js +931 -122
  80. package/src/typechecker/index.js +459 -67
  81. package/src/typechecker/init-order.js +330 -0
  82. package/src/typechecker/resolve.js +451 -56
  83. package/src/typechecker/statements.js +90 -9
  84. package/src/typechecker/stdlib/core.js +333 -55
  85. package/src/typechecker/stdlib/excluded.js +898 -0
  86. package/src/typechecker/stdlib/extended.js +322 -26
  87. package/src/typechecker/{stdlib.js → stdlib/index.js} +5 -5
  88. package/src/typechecker/stdlib/simd.js +65 -15
  89. package/src/typechecker/termination.js +1 -1
  90. package/src/typechecker/types.js +149 -25
  91. package/stdlib/bytes/iter.go +192 -0
  92. package/stdlib/bytes/search.go +240 -0
  93. package/stdlib/bytes/split.go +218 -0
  94. package/stdlib/cmp/cmp.go +65 -0
  95. package/stdlib/encoding/json/errors.go +31 -0
  96. package/stdlib/encoding/json/indent.go +71 -0
  97. package/stdlib/encoding/json/number.go +12 -0
  98. package/stdlib/encoding/json/stream.go +173 -0
  99. package/stdlib/errors/overlay.go +12 -0
  100. package/stdlib/hash/hash.go +53 -0
  101. package/stdlib/internal/jsonrt/dec.go +738 -0
  102. package/stdlib/internal/jsonrt/enc.go +366 -0
  103. package/stdlib/internal/jsonrt/indent.go +135 -0
  104. package/stdlib/internal/jsonrt/number.go +27 -0
  105. package/stdlib/internal/jsonrt/reader.go +73 -0
  106. package/stdlib/internal/jsonrt/scanner.go +649 -0
  107. package/stdlib/io/io.go +346 -0
  108. package/stdlib/iter/iter.go +18 -0
  109. package/stdlib/maps/iter.go +65 -0
  110. package/stdlib/math/extra.go +270 -0
  111. package/stdlib/slices/extra.go +73 -0
  112. package/stdlib/slices/iter.go +113 -0
  113. package/stdlib/sort/sort.go +561 -0
  114. package/stdlib/strconv/quote.go +341 -0
  115. package/stdlib/strings/extra.go +35 -0
  116. package/stdlib/strings/iter.go +122 -0
  117. package/stdlib/sync/extra.go +105 -0
  118. package/stdlib/unicode/unicode.go +112 -0
  119. package/stdlib/unicode/utf8/bytes.go +239 -0
  120. package/src/backend/wasm/const-fold.js +0 -205
  121. package/src/backend/wasm/emit-stdlib.js +0 -13
  122. /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
  123. /package/src/{colors.js → cli/colors.js} +0 -0
  124. /package/src/{dev-server.js → cli/dev-server.js} +0 -0
  125. /package/src/{minifier.js → cli/minifier.js} +0 -0
  126. /package/src/{project-config.js → cli/project-config.js} +0 -0
  127. /package/src/{pwa.js → cli/pwa.js} +0 -0
  128. /package/src/{templ-lexer.js → lexer/templ-lexer.js} +0 -0
@@ -0,0 +1,346 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
5
+ // Overlay on the emitter-backed io package.
6
+ package io
7
+
8
+ import (
9
+ "errors"
10
+ )
11
+
12
+ // Seek whence values.
13
+ const (
14
+ SeekStart = 0 // seek relative to the origin of the file
15
+ SeekCurrent = 1 // seek relative to the current offset
16
+ SeekEnd = 2 // seek relative to the end
17
+ )
18
+
19
+ // ErrShortWrite means that a write accepted fewer bytes than requested
20
+ // but failed to return an explicit error.
21
+ var ErrShortWrite = errors.New("short write")
22
+
23
+ // ErrShortBuffer means that a read required a longer buffer than was provided.
24
+ var ErrShortBuffer = errors.New("short buffer")
25
+
26
+ // ErrUnexpectedEOF means that EOF was encountered in the
27
+ // middle of reading a fixed-size block or data structure.
28
+ var ErrUnexpectedEOF = errors.New("unexpected EOF")
29
+
30
+ // ErrNoProgress is returned by some clients of a Reader when
31
+ // many calls to Read have failed to return any data or error.
32
+ var ErrNoProgress = errors.New("multiple Read calls return no data or error")
33
+
34
+ // ReadCloser is the interface that groups the basic Read and Close methods.
35
+ type ReadCloser interface {
36
+ Reader
37
+ Closer
38
+ }
39
+
40
+ // WriteCloser is the interface that groups the basic Write and Close methods.
41
+ type WriteCloser interface {
42
+ Writer
43
+ Closer
44
+ }
45
+
46
+ // ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
47
+ type ReadWriteCloser interface {
48
+ Reader
49
+ Writer
50
+ Closer
51
+ }
52
+
53
+ // ReadSeeker is the interface that groups the basic Read and Seek methods.
54
+ type ReadSeeker interface {
55
+ Reader
56
+ Seeker
57
+ }
58
+
59
+ // ReadSeekCloser is the interface that groups the basic Read, Seek and Close methods.
60
+ type ReadSeekCloser interface {
61
+ Reader
62
+ Seeker
63
+ Closer
64
+ }
65
+
66
+ // WriteSeeker is the interface that groups the basic Write and Seek methods.
67
+ type WriteSeeker interface {
68
+ Writer
69
+ Seeker
70
+ }
71
+
72
+ // ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
73
+ type ReadWriteSeeker interface {
74
+ Reader
75
+ Writer
76
+ Seeker
77
+ }
78
+
79
+ // Seeker is the interface that wraps the basic Seek method.
80
+ type Seeker interface {
81
+ Seek(offset int64, whence int) (int64, error)
82
+ }
83
+
84
+ // ReaderAt is the interface that wraps the basic ReadAt method.
85
+ type ReaderAt interface {
86
+ ReadAt(p []byte, off int64) (n int, err error)
87
+ }
88
+
89
+ // WriterAt is the interface that wraps the basic WriteAt method.
90
+ type WriterAt interface {
91
+ WriteAt(p []byte, off int64) (n int, err error)
92
+ }
93
+
94
+ // ByteReader is the interface that wraps the ReadByte method.
95
+ type ByteReader interface {
96
+ ReadByte() (byte, error)
97
+ }
98
+
99
+ // ByteScanner is the interface that adds the UnreadByte method to ByteReader.
100
+ type ByteScanner interface {
101
+ ByteReader
102
+ UnreadByte() error
103
+ }
104
+
105
+ // ByteWriter is the interface that wraps the WriteByte method.
106
+ type ByteWriter interface {
107
+ WriteByte(c byte) error
108
+ }
109
+
110
+ // RuneReader is the interface that wraps the ReadRune method.
111
+ type RuneReader interface {
112
+ ReadRune() (r rune, size int, err error)
113
+ }
114
+
115
+ // RuneScanner is the interface that adds the UnreadRune method to RuneReader.
116
+ type RuneScanner interface {
117
+ RuneReader
118
+ UnreadRune() error
119
+ }
120
+
121
+ // StringWriter is the interface that wraps the WriteString method.
122
+ type StringWriter interface {
123
+ WriteString(s string) (n int, err error)
124
+ }
125
+
126
+ // ReaderFrom is the interface that wraps the ReadFrom method.
127
+ type ReaderFrom interface {
128
+ ReadFrom(r Reader) (n int64, err error)
129
+ }
130
+
131
+ // WriterTo is the interface that wraps the WriteTo method.
132
+ type WriterTo interface {
133
+ WriteTo(w Writer) (n int64, err error)
134
+ }
135
+
136
+ // ReadAtLeast reads from r into buf until it has read at least min bytes.
137
+ func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
138
+ if len(buf) < min {
139
+ return 0, ErrShortBuffer
140
+ }
141
+ for n < min && err == nil {
142
+ var nn int
143
+ nn, err = r.Read(buf[n:])
144
+ n += nn
145
+ }
146
+ if n >= min {
147
+ err = nil
148
+ } else if n > 0 && err == EOF {
149
+ err = ErrUnexpectedEOF
150
+ }
151
+ return
152
+ }
153
+
154
+ // ReadFull reads exactly len(buf) bytes from r into buf.
155
+ func ReadFull(r Reader, buf []byte) (n int, err error) {
156
+ n, err = ReadAtLeast(r, buf, len(buf))
157
+ return
158
+ }
159
+
160
+ type nopCloser struct {
161
+ r Reader
162
+ }
163
+
164
+ func (n nopCloser) Read(p []byte) (int, error) {
165
+ rn, err := n.r.Read(p)
166
+ return rn, err
167
+ }
168
+
169
+ func (nopCloser) Close() error {
170
+ return nil
171
+ }
172
+
173
+ // NopCloser returns a ReadCloser with a no-op Close method wrapping r.
174
+ func NopCloser(r Reader) ReadCloser {
175
+ return nopCloser{r: r}
176
+ }
177
+
178
+ type teeReader struct {
179
+ r Reader
180
+ w Writer
181
+ }
182
+
183
+ func (t *teeReader) Read(p []byte) (n int, err error) {
184
+ n, err = t.r.Read(p)
185
+ if n > 0 {
186
+ if _, werr := t.w.Write(p[:n]); werr != nil {
187
+ return n, werr
188
+ }
189
+ }
190
+ return
191
+ }
192
+
193
+ // TeeReader returns a Reader that writes to w what it reads from r.
194
+ func TeeReader(r Reader, w Writer) Reader {
195
+ return &teeReader{r: r, w: w}
196
+ }
197
+
198
+ type multiReader struct {
199
+ readers []Reader
200
+ }
201
+
202
+ func (mr *multiReader) Read(p []byte) (n int, err error) {
203
+ for len(mr.readers) > 0 {
204
+ n, err = mr.readers[0].Read(p)
205
+ if err == EOF {
206
+ mr.readers = mr.readers[1:]
207
+ }
208
+ if n > 0 || err != EOF {
209
+ if err == EOF && len(mr.readers) > 0 {
210
+ err = nil
211
+ }
212
+ return
213
+ }
214
+ }
215
+ return 0, EOF
216
+ }
217
+
218
+ // MultiReader returns a Reader that's the logical concatenation of readers.
219
+ func MultiReader(readers ...Reader) Reader {
220
+ r := make([]Reader, len(readers))
221
+ copy(r, readers)
222
+ return &multiReader{readers: r}
223
+ }
224
+
225
+ type multiWriter struct {
226
+ writers []Writer
227
+ }
228
+
229
+ func (t *multiWriter) Write(p []byte) (n int, err error) {
230
+ for _, w := range t.writers {
231
+ n, err = w.Write(p)
232
+ if err != nil {
233
+ return
234
+ }
235
+ if n != len(p) {
236
+ err = ErrShortWrite
237
+ return
238
+ }
239
+ }
240
+ return len(p), nil
241
+ }
242
+
243
+ func (t *multiWriter) WriteString(s string) (n int, err error) {
244
+ p := []byte(s)
245
+ for _, w := range t.writers {
246
+ n, err = w.Write(p)
247
+ if err != nil {
248
+ return
249
+ }
250
+ if n != len(p) {
251
+ err = ErrShortWrite
252
+ return
253
+ }
254
+ }
255
+ return len(p), nil
256
+ }
257
+
258
+ // MultiWriter creates a writer that duplicates its writes to all writers.
259
+ func MultiWriter(writers ...Writer) Writer {
260
+ allWriters := make([]Writer, 0, len(writers))
261
+ for _, w := range writers {
262
+ if mw, ok := w.(*multiWriter); ok {
263
+ allWriters = append(allWriters, mw.writers...)
264
+ } else {
265
+ allWriters = append(allWriters, w)
266
+ }
267
+ }
268
+ return &multiWriter{writers: allWriters}
269
+ }
270
+
271
+ // SectionReader implements Read, Seek, and ReadAt on a section of an underlying ReaderAt.
272
+ type SectionReader struct {
273
+ r ReaderAt
274
+ base int64
275
+ off int64
276
+ limit int64
277
+ n int64
278
+ }
279
+
280
+ // NewSectionReader returns a SectionReader that reads from r
281
+ // starting at offset off and stops with EOF after n bytes.
282
+ func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
283
+ var remaining int64 = 1<<63 - 1 - off
284
+ if n <= remaining {
285
+ remaining = n
286
+ }
287
+ return &SectionReader{r: r, base: off, off: off, limit: off + remaining, n: n}
288
+ }
289
+
290
+ func (s *SectionReader) Read(p []byte) (n int, err error) {
291
+ if s.off >= s.limit {
292
+ return 0, EOF
293
+ }
294
+ if max := s.limit - s.off; int64(len(p)) > max {
295
+ p = p[0:max]
296
+ }
297
+ n, err = s.r.ReadAt(p, s.off)
298
+ s.off += int64(n)
299
+ return
300
+ }
301
+
302
+ var errWhence = errors.New("Seek: invalid whence")
303
+ var errOffset = errors.New("Seek: invalid offset")
304
+
305
+ func (s *SectionReader) Seek(offset int64, whence int) (int64, error) {
306
+ switch whence {
307
+ default:
308
+ return 0, errWhence
309
+ case SeekStart:
310
+ offset += s.base
311
+ case SeekCurrent:
312
+ offset += s.off
313
+ case SeekEnd:
314
+ offset += s.limit
315
+ }
316
+ if offset < s.base {
317
+ return 0, errOffset
318
+ }
319
+ s.off = offset
320
+ return offset - s.base, nil
321
+ }
322
+
323
+ func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) {
324
+ if off < 0 || off >= s.Size() {
325
+ return 0, EOF
326
+ }
327
+ off += s.base
328
+ if max := s.limit - off; int64(len(p)) > max {
329
+ p = p[0:max]
330
+ n, err = s.r.ReadAt(p, off)
331
+ if err == nil {
332
+ err = EOF
333
+ }
334
+ return n, err
335
+ }
336
+ n, err = s.r.ReadAt(p, off)
337
+ return n, err
338
+ }
339
+
340
+ // Size returns the size of the section in bytes.
341
+ func (s *SectionReader) Size() int64 { return s.limit - s.base }
342
+
343
+ // Outer returns the underlying ReaderAt and offsets for the section.
344
+ func (s *SectionReader) Outer() (r ReaderAt, off int64, n int64) {
345
+ return s.r, s.base, s.n
346
+ }
@@ -0,0 +1,18 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
5
+ // Package iter provides basic definitions related to iterators over
6
+ // sequences. Same API as Go's iter package; Pull and Pull2 need coroutines
7
+ // and are not available.
8
+ package iter
9
+
10
+ // Seq is an iterator over sequences of individual values. When called as
11
+ // seq(yield), seq calls yield(v) for each value v in the sequence, stopping
12
+ // early if yield returns false.
13
+ type Seq[V any] func(yield func(V) bool)
14
+
15
+ // Seq2 is an iterator over sequences of pairs of values, most commonly
16
+ // key-value pairs. When called as seq(yield), seq calls yield(k, v) for each
17
+ // pair (k, v) in the sequence, stopping early if yield returns false.
18
+ type Seq2[K, V any] func(yield func(K, V) bool)
@@ -0,0 +1,65 @@
1
+ //go:build gofront
2
+
3
+ //gofront:target both
4
+
5
+ // Overlay on the emitter-backed maps package: the iterator members are
6
+ // written in Go over iter.Seq and iter.Seq2 and merged into the maps
7
+ // namespace. Keys and Values return iterators, as in Go 1.23.
8
+ package maps
9
+
10
+ import "iter"
11
+
12
+ // All returns an iterator over key-value pairs from m.
13
+ // The iteration order is not specified and is not guaranteed
14
+ // to be the same from one call to the next.
15
+ func All[K comparable, V any](m map[K]V) iter.Seq2[K, V] {
16
+ return func(yield func(K, V) bool) {
17
+ for k, v := range m {
18
+ if !yield(k, v) {
19
+ return
20
+ }
21
+ }
22
+ }
23
+ }
24
+
25
+ // Keys returns an iterator over keys in m.
26
+ // The iteration order is not specified and is not guaranteed
27
+ // to be the same from one call to the next.
28
+ func Keys[K comparable, V any](m map[K]V) iter.Seq[K] {
29
+ return func(yield func(K) bool) {
30
+ for k := range m {
31
+ if !yield(k) {
32
+ return
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ // Values returns an iterator over values in m.
39
+ // The iteration order is not specified and is not guaranteed
40
+ // to be the same from one call to the next.
41
+ func Values[K comparable, V any](m map[K]V) iter.Seq[V] {
42
+ return func(yield func(V) bool) {
43
+ for _, v := range m {
44
+ if !yield(v) {
45
+ return
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ // Insert adds the key-value pairs from seq to m.
52
+ // If a key in seq already exists in m, its value will be overwritten.
53
+ func Insert[K comparable, V any](m map[K]V, seq iter.Seq2[K, V]) {
54
+ for k, v := range seq {
55
+ m[k] = v
56
+ }
57
+ }
58
+
59
+ // Collect collects key-value pairs from seq into a new map
60
+ // and returns it.
61
+ func Collect[K comparable, V any](seq iter.Seq2[K, V]) map[K]V {
62
+ m := make(map[K]V)
63
+ Insert(m, seq)
64
+ return m
65
+ }
@@ -0,0 +1,270 @@
1
+ package math
2
+
3
+ import "math/bits"
4
+
5
+ const (
6
+ mask = 0x7FF
7
+ shift = 52
8
+ bias = 1023
9
+ signMask uint64 = 1 << 63
10
+ fracMask uint64 = 1<<52 - 1
11
+ maskShift uint64 = 0x7FF0000000000000
12
+ biasShift uint64 = 0x3FE0000000000000
13
+ SmallestNormal = 2.2250738585072014e-308
14
+ halfMinusULP uint64 = (1 << (52 - 1)) - 1
15
+ uvinf uint64 = 0x7FF0000000000000
16
+ )
17
+
18
+ func normalize(x float64) (y float64, exp int) {
19
+ if Abs(x) < SmallestNormal {
20
+ return x * (1 << 52), -52
21
+ }
22
+ return x, 0
23
+ }
24
+
25
+ func Frexp(f float64) (frac float64, exp int) {
26
+ switch {
27
+ case f == 0:
28
+ return f, 0
29
+ case IsInf(f, 0) || IsNaN(f):
30
+ return f, 0
31
+ }
32
+ f, exp = normalize(f)
33
+ x := Float64bits(f)
34
+ exp += int((x>>shift)&mask) - bias + 1
35
+ x = x &^ maskShift
36
+ x |= biasShift
37
+ frac = Float64frombits(x)
38
+ return
39
+ }
40
+
41
+ func Ldexp(frac float64, exp int) float64 {
42
+ switch {
43
+ case frac == 0:
44
+ return frac
45
+ case IsInf(frac, 0) || IsNaN(frac):
46
+ return frac
47
+ }
48
+ f, e := normalize(frac)
49
+ exp += e
50
+ x := Float64bits(f)
51
+ exp += int(x>>shift)&mask - bias
52
+ if exp < -1075 {
53
+ return Copysign(0, f)
54
+ }
55
+ if exp > 1023 {
56
+ if f < 0 {
57
+ return Inf(-1)
58
+ }
59
+ return Inf(1)
60
+ }
61
+ var m float64 = 1
62
+ if exp < -1022 {
63
+ exp += 53
64
+ m = 1.0 / (1 << 53)
65
+ }
66
+ x = x &^ maskShift
67
+ x |= uint64(exp+bias) << 52
68
+ return m * Float64frombits(x)
69
+ }
70
+
71
+ func Modf(f float64) (int float64, frac float64) {
72
+ if IsInf(f, 0) {
73
+ return f, NaN()
74
+ }
75
+ if IsNaN(f) {
76
+ return NaN(), NaN()
77
+ }
78
+ int = Trunc(f)
79
+ frac = Copysign(f-int, f)
80
+ return
81
+ }
82
+
83
+ func RoundToEven(x float64) float64 {
84
+ b := Float64bits(x)
85
+ e := uint(b>>shift) & mask
86
+ if e >= bias {
87
+ e -= bias
88
+ b += (halfMinusULP + (b>>(shift-e))&1) >> e
89
+ b = b &^ (fracMask >> e)
90
+ } else if e == bias-1 && b&fracMask != 0 {
91
+ b = b&signMask | 0x3FF0000000000000
92
+ } else {
93
+ b &= signMask
94
+ }
95
+ return Float64frombits(b)
96
+ }
97
+
98
+ func Nextafter32(x, y float32) (r float32) {
99
+ switch {
100
+ case IsNaN(float64(x)) || IsNaN(float64(y)):
101
+ r = float32(NaN())
102
+ case x == y:
103
+ r = x
104
+ case x == 0:
105
+ r = float32(Copysign(float64(Float32frombits(1)), float64(y)))
106
+ case (y > x) == (x > 0):
107
+ r = Float32frombits(Float32bits(x) + 1)
108
+ default:
109
+ r = Float32frombits(Float32bits(x) - 1)
110
+ }
111
+ return
112
+ }
113
+
114
+ func Nextafter(x, y float64) (r float64) {
115
+ switch {
116
+ case IsNaN(x) || IsNaN(y):
117
+ r = NaN()
118
+ case x == y:
119
+ r = x
120
+ case x == 0:
121
+ r = Copysign(Float64frombits(1), y)
122
+ case (y > x) == (x > 0):
123
+ r = Float64frombits(Float64bits(x) + 1)
124
+ default:
125
+ r = Float64frombits(Float64bits(x) - 1)
126
+ }
127
+ return
128
+ }
129
+
130
+ // --- FMA ---
131
+
132
+ func fmaZero(x uint64) uint64 {
133
+ if x == 0 {
134
+ return 1
135
+ }
136
+ return 0
137
+ }
138
+
139
+ func fmaNonzero(x uint64) uint64 {
140
+ if x != 0 {
141
+ return 1
142
+ }
143
+ return 0
144
+ }
145
+
146
+ func fmaShl(u1, u2 uint64, n uint) (r1 uint64, r2 uint64) {
147
+ r1 = u1<<n | u2>>(64-n) | u2<<(n-64)
148
+ r2 = u2 << n
149
+ return
150
+ }
151
+
152
+ func fmaShr(u1, u2 uint64, n uint) (r1 uint64, r2 uint64) {
153
+ r2 = u2>>n | u1<<(64-n) | u1>>(n-64)
154
+ r1 = u1 >> n
155
+ return
156
+ }
157
+
158
+ func fmaShrcompress(u1, u2 uint64, n uint) (r1 uint64, r2 uint64) {
159
+ switch {
160
+ case n == 0:
161
+ return u1, u2
162
+ case n == 64:
163
+ return 0, u1 | fmaNonzero(u2)
164
+ case n >= 128:
165
+ return 0, fmaNonzero(u1 | u2)
166
+ case n < 64:
167
+ r1, r2 = fmaShr(u1, u2, n)
168
+ r2 |= fmaNonzero(u2 & (1<<n - 1))
169
+ case n < 128:
170
+ r1, r2 = fmaShr(u1, u2, n)
171
+ r2 |= fmaNonzero(u1&(1<<(n-64)-1) | u2)
172
+ }
173
+ return
174
+ }
175
+
176
+ func fmaLz(u1, u2 uint64) (l int32) {
177
+ l = int32(bits.LeadingZeros64(u1))
178
+ if l == 64 {
179
+ l += int32(bits.LeadingZeros64(u2))
180
+ }
181
+ return l
182
+ }
183
+
184
+ func fmaSplit(b uint64) (sign uint32, exp int32, mantissa uint64) {
185
+ sign = uint32(b >> 63)
186
+ exp = int32(b>>52) & mask
187
+ mantissa = b & fracMask
188
+ if exp == 0 {
189
+ shift := uint(bits.LeadingZeros64(mantissa) - 11)
190
+ mantissa <<= shift
191
+ exp = 1 - int32(shift)
192
+ } else {
193
+ mantissa |= 1 << 52
194
+ }
195
+ return
196
+ }
197
+
198
+ func fmaSpecial(x, y, z float64, bx, by, bz uint64) (float64, bool) {
199
+ if x == 0.0 || y == 0.0 || bx&uvinf == uvinf || by&uvinf == uvinf {
200
+ return x*y + z, true
201
+ }
202
+ if z == 0.0 {
203
+ return x * y, true
204
+ }
205
+ if bz&uvinf == uvinf {
206
+ return z, true
207
+ }
208
+ return 0, false
209
+ }
210
+
211
+ func fmaRound(ps uint32, pe int32, m uint64) float64 {
212
+ if pe > 1022+bias || pe == 1022+bias && (m+1<<9)>>63 == 1 {
213
+ return Float64frombits(uint64(ps)<<63 | uvinf)
214
+ }
215
+ if pe < 0 {
216
+ n := uint(-pe)
217
+ m = m>>n | fmaNonzero(m&(1<<n-1))
218
+ pe = 0
219
+ }
220
+ m = ((m + 1<<9) >> 10) & ^fmaZero((m&(1<<10-1))^1<<9)
221
+ pe &= -int32(fmaNonzero(m))
222
+ return Float64frombits(uint64(ps)<<63 + uint64(pe)<<52 + m)
223
+ }
224
+
225
+ func FMA(x, y, z float64) float64 {
226
+ bx, by, bz := Float64bits(x), Float64bits(y), Float64bits(z)
227
+ if val, ok := fmaSpecial(x, y, z, bx, by, bz); ok {
228
+ return val
229
+ }
230
+
231
+ xs, xe, xm := fmaSplit(bx)
232
+ ys, ye, ym := fmaSplit(by)
233
+ zs, ze, zm := fmaSplit(bz)
234
+
235
+ pe := xe + ye - bias + 1
236
+ pm1, pm2 := bits.Mul64(xm<<10, ym<<11)
237
+ zm1, zm2 := zm<<10, uint64(0)
238
+ ps := xs ^ ys
239
+
240
+ is62zero := uint((^pm1 >> 62) & 1)
241
+ pm1, pm2 = fmaShl(pm1, pm2, is62zero)
242
+ pe -= int32(is62zero)
243
+
244
+ if pe < ze || pe == ze && pm1 < zm1 {
245
+ ps, pe, pm1, pm2, zs, ze, zm1, zm2 = zs, ze, zm1, zm2, ps, pe, pm1, pm2
246
+ }
247
+
248
+ if ps != zs && pe == ze && pm1 == zm1 && pm2 == zm2 {
249
+ return 0
250
+ }
251
+
252
+ zm1, zm2 = fmaShrcompress(zm1, zm2, uint(pe-ze))
253
+
254
+ var m, c uint64
255
+ if ps == zs {
256
+ pm2, c = bits.Add64(pm2, zm2, 0)
257
+ pm1, _ = bits.Add64(pm1, zm1, c)
258
+ pe -= int32(^pm1 >> 63)
259
+ pm1, m = fmaShrcompress(pm1, pm2, uint(64+pm1>>63))
260
+ } else {
261
+ pm2, c = bits.Sub64(pm2, zm2, 0)
262
+ pm1, _ = bits.Sub64(pm1, zm1, c)
263
+ nz := fmaLz(pm1, pm2)
264
+ pe -= nz
265
+ m, pm2 = fmaShl(pm1, pm2, uint(nz-1))
266
+ m |= fmaNonzero(pm2)
267
+ }
268
+
269
+ return fmaRound(ps, pe, m)
270
+ }