goscript 0.0.26 → 0.0.29
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 +4 -4
- package/cmd/goscript/cmd_compile.go +0 -3
- package/cmd/goscript/deps.go +11 -0
- package/compiler/analysis.go +298 -55
- package/compiler/assignment.go +2 -2
- package/compiler/builtin_test.go +1 -1
- package/compiler/compiler.go +200 -68
- package/compiler/compiler_test.go +17 -24
- package/compiler/composite-lit.go +32 -8
- package/compiler/decl.go +6 -6
- package/compiler/expr-call.go +170 -15
- package/compiler/expr-selector.go +100 -0
- package/compiler/expr.go +1 -1
- package/compiler/protobuf.go +557 -0
- package/compiler/spec-struct.go +4 -0
- package/compiler/spec-value.go +89 -10
- package/compiler/spec.go +254 -1
- package/compiler/stmt-assign.go +35 -0
- package/compiler/type-assert.go +87 -0
- package/compiler/type.go +4 -1
- package/dist/gs/builtin/builtin.d.ts +20 -1
- package/dist/gs/builtin/builtin.js +95 -4
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +1 -1
- package/dist/gs/builtin/slice.js +21 -2
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/errors/errors.d.ts +5 -6
- package/dist/gs/errors/errors.js.map +1 -1
- package/dist/gs/internal/oserror/errors.d.ts +6 -0
- package/dist/gs/internal/oserror/errors.js +7 -0
- package/dist/gs/internal/oserror/errors.js.map +1 -0
- package/dist/gs/internal/oserror/index.d.ts +1 -0
- package/dist/gs/internal/oserror/index.js +2 -0
- package/dist/gs/internal/oserror/index.js.map +1 -0
- package/dist/gs/io/fs/format.d.ts +3 -0
- package/dist/gs/io/fs/format.js +56 -0
- package/dist/gs/io/fs/format.js.map +1 -0
- package/dist/gs/io/fs/fs.d.ts +79 -0
- package/dist/gs/io/fs/fs.js +200 -0
- package/dist/gs/io/fs/fs.js.map +1 -0
- package/dist/gs/io/fs/glob.d.ts +10 -0
- package/dist/gs/io/fs/glob.js +141 -0
- package/dist/gs/io/fs/glob.js.map +1 -0
- package/dist/gs/io/fs/index.d.ts +8 -0
- package/dist/gs/io/fs/index.js +9 -0
- package/dist/gs/io/fs/index.js.map +1 -0
- package/dist/gs/io/fs/readdir.d.ts +7 -0
- package/dist/gs/io/fs/readdir.js +152 -0
- package/dist/gs/io/fs/readdir.js.map +1 -0
- package/dist/gs/io/fs/readfile.d.ts +6 -0
- package/dist/gs/io/fs/readfile.js +118 -0
- package/dist/gs/io/fs/readfile.js.map +1 -0
- package/dist/gs/io/fs/stat.d.ts +6 -0
- package/dist/gs/io/fs/stat.js +87 -0
- package/dist/gs/io/fs/stat.js.map +1 -0
- package/dist/gs/io/fs/sub.d.ts +6 -0
- package/dist/gs/io/fs/sub.js +172 -0
- package/dist/gs/io/fs/sub.js.map +1 -0
- package/dist/gs/io/fs/walk.d.ts +7 -0
- package/dist/gs/io/fs/walk.js +76 -0
- package/dist/gs/io/fs/walk.js.map +1 -0
- package/dist/gs/io/index.d.ts +1 -0
- package/dist/gs/io/index.js +2 -0
- package/dist/gs/io/index.js.map +1 -0
- package/dist/gs/io/io.d.ts +107 -0
- package/dist/gs/io/io.js +385 -0
- package/dist/gs/io/io.js.map +1 -0
- package/dist/gs/path/index.d.ts +2 -0
- package/dist/gs/path/index.js +3 -0
- package/dist/gs/path/index.js.map +1 -0
- package/dist/gs/path/match.d.ts +6 -0
- package/dist/gs/path/match.js +281 -0
- package/dist/gs/path/match.js.map +1 -0
- package/dist/gs/path/path.d.ts +7 -0
- package/dist/gs/path/path.js +256 -0
- package/dist/gs/path/path.js.map +1 -0
- package/dist/gs/strings/builder.d.ts +18 -0
- package/dist/gs/strings/builder.js +205 -0
- package/dist/gs/strings/builder.js.map +1 -0
- package/dist/gs/strings/clone.d.ts +1 -0
- package/dist/gs/strings/clone.js +16 -0
- package/dist/gs/strings/clone.js.map +1 -0
- package/dist/gs/strings/compare.d.ts +1 -0
- package/dist/gs/strings/compare.js +14 -0
- package/dist/gs/strings/compare.js.map +1 -0
- package/dist/gs/strings/index.d.ts +2 -0
- package/dist/gs/strings/index.js +3 -0
- package/dist/gs/strings/index.js.map +1 -0
- package/dist/gs/strings/iter.d.ts +8 -0
- package/dist/gs/strings/iter.js +160 -0
- package/dist/gs/strings/iter.js.map +1 -0
- package/dist/gs/strings/reader.d.ts +34 -0
- package/dist/gs/strings/reader.js +418 -0
- package/dist/gs/strings/reader.js.map +1 -0
- package/dist/gs/strings/replace.d.ts +106 -0
- package/dist/gs/strings/replace.js +1136 -0
- package/dist/gs/strings/replace.js.map +1 -0
- package/dist/gs/strings/search.d.ts +24 -0
- package/dist/gs/strings/search.js +169 -0
- package/dist/gs/strings/search.js.map +1 -0
- package/dist/gs/strings/strings.d.ts +47 -0
- package/dist/gs/strings/strings.js +418 -0
- package/dist/gs/strings/strings.js.map +1 -0
- package/dist/gs/stringslite/index.d.ts +1 -0
- package/dist/gs/stringslite/index.js +2 -0
- package/dist/gs/stringslite/index.js.map +1 -0
- package/dist/gs/stringslite/strings.d.ts +11 -0
- package/dist/gs/stringslite/strings.js +67 -0
- package/dist/gs/stringslite/strings.js.map +1 -0
- package/dist/gs/sync/index.d.ts +1 -0
- package/dist/gs/sync/index.js +2 -0
- package/dist/gs/sync/index.js.map +1 -0
- package/dist/gs/sync/sync.d.ts +79 -0
- package/dist/gs/sync/sync.js +392 -0
- package/dist/gs/sync/sync.js.map +1 -0
- package/dist/gs/time/time.d.ts +11 -2
- package/dist/gs/time/time.js +337 -12
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unicode/index.d.ts +1 -0
- package/dist/gs/unicode/index.js +2 -0
- package/dist/gs/unicode/index.js.map +1 -0
- package/dist/gs/unicode/unicode.d.ts +105 -0
- package/dist/gs/unicode/unicode.js +332 -0
- package/dist/gs/unicode/unicode.js.map +1 -0
- package/dist/gs/unicode/utf8/index.d.ts +1 -0
- package/dist/gs/unicode/utf8/index.js +3 -0
- package/dist/gs/unicode/utf8/index.js.map +1 -0
- package/dist/gs/unicode/utf8/utf8.d.ts +20 -0
- package/dist/gs/unicode/utf8/utf8.js +196 -0
- package/dist/gs/unicode/utf8/utf8.js.map +1 -0
- package/dist/gs/unsafe/index.d.ts +1 -0
- package/dist/gs/unsafe/index.js +2 -0
- package/dist/gs/unsafe/index.js.map +1 -0
- package/dist/gs/unsafe/unsafe.d.ts +11 -0
- package/dist/gs/unsafe/unsafe.js +44 -0
- package/dist/gs/unsafe/unsafe.js.map +1 -0
- package/go.mod +2 -1
- package/go.sum +6 -2
- package/gs/README.md +6 -0
- package/gs/builtin/builtin.ts +171 -0
- package/gs/builtin/channel.ts +683 -0
- package/gs/builtin/defer.ts +58 -0
- package/gs/builtin/index.ts +1 -0
- package/gs/builtin/io.ts +22 -0
- package/gs/builtin/map.ts +50 -0
- package/gs/builtin/slice.ts +1030 -0
- package/gs/builtin/type.ts +1106 -0
- package/gs/builtin/varRef.ts +25 -0
- package/gs/cmp/godoc.txt +8 -0
- package/gs/cmp/index.ts +29 -0
- package/gs/context/context.ts +401 -0
- package/gs/context/godoc.txt +69 -0
- package/gs/context/index.ts +1 -0
- package/gs/errors/errors.ts +223 -0
- package/gs/errors/godoc.txt +63 -0
- package/gs/errors/index.ts +1 -0
- package/gs/internal/goarch/godoc.txt +39 -0
- package/gs/internal/goarch/index.ts +18 -0
- package/gs/internal/oserror/errors.ts +14 -0
- package/gs/internal/oserror/index.ts +1 -0
- package/gs/io/fs/format.ts +65 -0
- package/gs/io/fs/fs.ts +359 -0
- package/gs/io/fs/glob.ts +167 -0
- package/gs/io/fs/godoc.txt +35 -0
- package/gs/io/fs/index.ts +8 -0
- package/gs/io/fs/readdir.ts +126 -0
- package/gs/io/fs/readfile.ts +77 -0
- package/gs/io/fs/stat.ts +38 -0
- package/gs/io/fs/sub.ts +208 -0
- package/gs/io/fs/walk.ts +89 -0
- package/gs/io/godoc.txt +61 -0
- package/gs/io/index.ts +1 -0
- package/gs/io/io.go +75 -0
- package/gs/io/io.ts +546 -0
- package/gs/iter/godoc.txt +203 -0
- package/gs/iter/index.ts +1 -0
- package/gs/iter/iter.ts +117 -0
- package/gs/math/bits/index.ts +356 -0
- package/gs/math/godoc.txt +76 -0
- package/gs/path/index.ts +2 -0
- package/gs/path/match.ts +307 -0
- package/gs/path/path.ts +301 -0
- package/gs/runtime/godoc.txt +331 -0
- package/gs/runtime/index.ts +1 -0
- package/gs/runtime/runtime.ts +178 -0
- package/gs/slices/godoc.txt +44 -0
- package/gs/slices/index.ts +1 -0
- package/gs/slices/slices.ts +22 -0
- package/gs/strings/builder.test.ts +121 -0
- package/gs/strings/builder.ts +223 -0
- package/gs/strings/clone.test.ts +43 -0
- package/gs/strings/clone.ts +17 -0
- package/gs/strings/compare.test.ts +84 -0
- package/gs/strings/compare.ts +13 -0
- package/gs/strings/godoc.txt +66 -0
- package/gs/strings/index.ts +2 -0
- package/gs/strings/iter.test.ts +343 -0
- package/gs/strings/iter.ts +171 -0
- package/gs/strings/reader.test.ts +242 -0
- package/gs/strings/reader.ts +451 -0
- package/gs/strings/replace.test.ts +181 -0
- package/gs/strings/replace.ts +1310 -0
- package/gs/strings/search.test.ts +214 -0
- package/gs/strings/search.ts +213 -0
- package/gs/strings/strings.test.ts +477 -0
- package/gs/strings/strings.ts +510 -0
- package/gs/stringslite/godoc.txt +17 -0
- package/gs/stringslite/index.ts +1 -0
- package/gs/stringslite/strings.ts +82 -0
- package/gs/sync/godoc.txt +21 -0
- package/gs/sync/index.ts +1 -0
- package/gs/sync/sync.go +64 -0
- package/gs/sync/sync.ts +449 -0
- package/gs/time/godoc.txt +116 -0
- package/gs/time/index.ts +1 -0
- package/gs/time/time.ts +585 -0
- package/gs/unicode/godoc.txt +52 -0
- package/gs/unicode/index.ts +1 -0
- package/gs/unicode/unicode.go +38 -0
- package/gs/unicode/unicode.ts +418 -0
- package/gs/unicode/utf8/godoc.txt +22 -0
- package/gs/unicode/utf8/index.ts +2 -0
- package/gs/unicode/utf8/utf8.ts +227 -0
- package/gs/unsafe/godoc.txt +19 -0
- package/gs/unsafe/index.ts +1 -0
- package/gs/unsafe/unsafe.test.ts +68 -0
- package/gs/unsafe/unsafe.ts +77 -0
- package/package.json +4 -3
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
package iter // import "iter"
|
|
2
|
+
|
|
3
|
+
Package iter provides basic definitions and operations related to iterators over
|
|
4
|
+
sequences.
|
|
5
|
+
|
|
6
|
+
# Iterators
|
|
7
|
+
|
|
8
|
+
An iterator is a function that passes successive elements of a sequence to a
|
|
9
|
+
callback function, conventionally named yield. The function stops either when
|
|
10
|
+
the sequence is finished or when yield returns false, indicating to stop the
|
|
11
|
+
iteration early. This package defines Seq and Seq2 (pronounced like seek—the
|
|
12
|
+
first syllable of sequence) as shorthands for iterators that pass 1 or 2 values
|
|
13
|
+
per sequence element to yield:
|
|
14
|
+
|
|
15
|
+
type (
|
|
16
|
+
Seq[V any] func(yield func(V) bool)
|
|
17
|
+
Seq2[K, V any] func(yield func(K, V) bool)
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
Seq2 represents a sequence of paired values, conventionally key-value or
|
|
21
|
+
index-value pairs.
|
|
22
|
+
|
|
23
|
+
Yield returns true if the iterator should continue with the next element in the
|
|
24
|
+
sequence, false if it should stop.
|
|
25
|
+
|
|
26
|
+
For instance, maps.Keys returns an iterator that produces the sequence of keys
|
|
27
|
+
of the map m, implemented as follows:
|
|
28
|
+
|
|
29
|
+
func Keys[Map ~map[K]V, K comparable, V any](m Map) iter.Seq[K] {
|
|
30
|
+
return func(yield func(K) bool) {
|
|
31
|
+
for k := range m {
|
|
32
|
+
if !yield(k) {
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
Further examples can be found in The Go Blog: Range Over Function Types.
|
|
40
|
+
|
|
41
|
+
Iterator functions are most often called by a range loop, as in:
|
|
42
|
+
|
|
43
|
+
func PrintAll[V any](seq iter.Seq[V]) {
|
|
44
|
+
for v := range seq {
|
|
45
|
+
fmt.Println(v)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Naming Conventions
|
|
50
|
+
|
|
51
|
+
Iterator functions and methods are named for the sequence being walked:
|
|
52
|
+
|
|
53
|
+
// All returns an iterator over all elements in s.
|
|
54
|
+
func (s *Set[V]) All() iter.Seq[V]
|
|
55
|
+
|
|
56
|
+
The iterator method on a collection type is conventionally named All, because it
|
|
57
|
+
iterates a sequence of all the values in the collection.
|
|
58
|
+
|
|
59
|
+
For a type containing multiple possible sequences, the iterator's name can
|
|
60
|
+
indicate which sequence is being provided:
|
|
61
|
+
|
|
62
|
+
// Cities returns an iterator over the major cities in the country.
|
|
63
|
+
func (c *Country) Cities() iter.Seq[*City]
|
|
64
|
+
|
|
65
|
+
// Languages returns an iterator over the official spoken languages of the country.
|
|
66
|
+
func (c *Country) Languages() iter.Seq[string]
|
|
67
|
+
|
|
68
|
+
If an iterator requires additional configuration, the constructor function can
|
|
69
|
+
take additional configuration arguments:
|
|
70
|
+
|
|
71
|
+
// Scan returns an iterator over key-value pairs with min ≤ key ≤ max.
|
|
72
|
+
func (m *Map[K, V]) Scan(min, max K) iter.Seq2[K, V]
|
|
73
|
+
|
|
74
|
+
// Split returns an iterator over the (possibly-empty) substrings of s
|
|
75
|
+
// separated by sep.
|
|
76
|
+
func Split(s, sep string) iter.Seq[string]
|
|
77
|
+
|
|
78
|
+
When there are multiple possible iteration orders, the method name may indicate
|
|
79
|
+
that order:
|
|
80
|
+
|
|
81
|
+
// All returns an iterator over the list from head to tail.
|
|
82
|
+
func (l *List[V]) All() iter.Seq[V]
|
|
83
|
+
|
|
84
|
+
// Backward returns an iterator over the list from tail to head.
|
|
85
|
+
func (l *List[V]) Backward() iter.Seq[V]
|
|
86
|
+
|
|
87
|
+
// Preorder returns an iterator over all nodes of the syntax tree
|
|
88
|
+
// beneath (and including) the specified root, in depth-first preorder,
|
|
89
|
+
// visiting a parent node before its children.
|
|
90
|
+
func Preorder(root Node) iter.Seq[Node]
|
|
91
|
+
|
|
92
|
+
# Single-Use Iterators
|
|
93
|
+
|
|
94
|
+
Most iterators provide the ability to walk an entire sequence: when called,
|
|
95
|
+
the iterator does any setup necessary to start the sequence, then calls yield
|
|
96
|
+
on successive elements of the sequence, and then cleans up before returning.
|
|
97
|
+
Calling the iterator again walks the sequence again.
|
|
98
|
+
|
|
99
|
+
Some iterators break that convention, providing the ability to walk a sequence
|
|
100
|
+
only once. These “single-use iterators” typically report values from a data
|
|
101
|
+
stream that cannot be rewound to start over. Calling the iterator again after
|
|
102
|
+
stopping early may continue the stream, but calling it again after the sequence
|
|
103
|
+
is finished will yield no values at all. Doc comments for functions or methods
|
|
104
|
+
that return single-use iterators should document this fact:
|
|
105
|
+
|
|
106
|
+
// Lines returns an iterator over lines read from r.
|
|
107
|
+
// It returns a single-use iterator.
|
|
108
|
+
func (r *Reader) Lines() iter.Seq[string]
|
|
109
|
+
|
|
110
|
+
# Pulling Values
|
|
111
|
+
|
|
112
|
+
Functions and methods that accept or return iterators should use the standard
|
|
113
|
+
Seq or Seq2 types, to ensure compatibility with range loops and other iterator
|
|
114
|
+
adapters. The standard iterators can be thought of as “push iterators”, which
|
|
115
|
+
push values to the yield function.
|
|
116
|
+
|
|
117
|
+
Sometimes a range loop is not the most natural way to consume values of the
|
|
118
|
+
sequence. In this case, Pull converts a standard push iterator to a “pull
|
|
119
|
+
iterator”, which can be called to pull one value at a time from the sequence.
|
|
120
|
+
Pull starts an iterator and returns a pair of functions—next and stop—which
|
|
121
|
+
return the next value from the iterator and stop it, respectively.
|
|
122
|
+
|
|
123
|
+
For example:
|
|
124
|
+
|
|
125
|
+
// Pairs returns an iterator over successive pairs of values from seq.
|
|
126
|
+
func Pairs[V any](seq iter.Seq[V]) iter.Seq2[V, V] {
|
|
127
|
+
return func(yield func(V, V) bool) {
|
|
128
|
+
next, stop := iter.Pull(seq)
|
|
129
|
+
defer stop()
|
|
130
|
+
for {
|
|
131
|
+
v1, ok1 := next()
|
|
132
|
+
if !ok1 {
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
v2, ok2 := next()
|
|
136
|
+
// If ok2 is false, v2 should be the
|
|
137
|
+
// zero value; yield one last pair.
|
|
138
|
+
if !yield(v1, v2) {
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
if !ok2 {
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
If clients do not consume the sequence to completion, they must call stop, which
|
|
149
|
+
allows the iterator function to finish and return. As shown in the example,
|
|
150
|
+
the conventional way to ensure this is to use defer.
|
|
151
|
+
|
|
152
|
+
# Standard Library Usage
|
|
153
|
+
|
|
154
|
+
A few packages in the standard library provide iterator-based APIs, most notably
|
|
155
|
+
the maps and slices packages. For example, maps.Keys returns an iterator over
|
|
156
|
+
the keys of a map, while slices.Sorted collects the values of an iterator into a
|
|
157
|
+
slice, sorts them, and returns the slice, so to iterate over the sorted keys of
|
|
158
|
+
a map:
|
|
159
|
+
|
|
160
|
+
for _, key := range slices.Sorted(maps.Keys(m)) {
|
|
161
|
+
...
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# Mutation
|
|
165
|
+
|
|
166
|
+
Iterators provide only the values of the sequence, not any direct way to modify
|
|
167
|
+
it. If an iterator wishes to provide a mechanism for modifying a sequence
|
|
168
|
+
during iteration, the usual approach is to define a position type with the extra
|
|
169
|
+
operations and then provide an iterator over positions.
|
|
170
|
+
|
|
171
|
+
For example, a tree implementation might provide:
|
|
172
|
+
|
|
173
|
+
// Positions returns an iterator over positions in the sequence.
|
|
174
|
+
func (t *Tree[V]) Positions() iter.Seq[*Pos]
|
|
175
|
+
|
|
176
|
+
// A Pos represents a position in the sequence.
|
|
177
|
+
// It is only valid during the yield call it is passed to.
|
|
178
|
+
type Pos[V any] struct { ... }
|
|
179
|
+
|
|
180
|
+
// Pos returns the value at the cursor.
|
|
181
|
+
func (p *Pos[V]) Value() V
|
|
182
|
+
|
|
183
|
+
// Delete deletes the value at this point in the iteration.
|
|
184
|
+
func (p *Pos[V]) Delete()
|
|
185
|
+
|
|
186
|
+
// Set changes the value v at the cursor.
|
|
187
|
+
func (p *Pos[V]) Set(v V)
|
|
188
|
+
|
|
189
|
+
And then a client could delete boring values from the tree using:
|
|
190
|
+
|
|
191
|
+
for p := range t.Positions() {
|
|
192
|
+
if boring(p.Value()) {
|
|
193
|
+
p.Delete()
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
[The Go Blog: Range Over Function Types]: https://go.dev/blog/range-functions
|
|
198
|
+
[range loop]: https://go.dev/ref/spec#For_range
|
|
199
|
+
|
|
200
|
+
func Pull[V any](seq Seq[V]) (next func() (V, bool), stop func())
|
|
201
|
+
func Pull2[K, V any](seq Seq2[K, V]) (next func() (K, V, bool), stop func())
|
|
202
|
+
type Seq[V any] func(yield func(V) bool)
|
|
203
|
+
type Seq2[K, V any] func(yield func(K, V) bool)
|
package/gs/iter/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './iter.js'
|
package/gs/iter/iter.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// TypeScript implementation of Go's iter package
|
|
2
|
+
// This provides iterator types and functions
|
|
3
|
+
|
|
4
|
+
// Seq is an iterator over sequences of individual values
|
|
5
|
+
export type Seq<V> = (_yield: (value: V) => boolean) => void
|
|
6
|
+
|
|
7
|
+
// Seq2 is an iterator over sequences of pairs of values
|
|
8
|
+
export type Seq2<K, V> = (_yield: (key: K, value: V) => boolean) => void
|
|
9
|
+
|
|
10
|
+
// Pull converts the "push-style" iterator sequence seq into a "pull-style" iterator
|
|
11
|
+
// Returns a function that returns the next value and a boolean indicating if iteration should continue
|
|
12
|
+
export function Pull<V>(
|
|
13
|
+
seq: Seq<V>,
|
|
14
|
+
): [() => [V | undefined, boolean], () => void] {
|
|
15
|
+
let done = false
|
|
16
|
+
let nextValue: V | undefined
|
|
17
|
+
let hasNext = false
|
|
18
|
+
|
|
19
|
+
const iterator = seq(function (value: V): boolean {
|
|
20
|
+
nextValue = value
|
|
21
|
+
hasNext = true
|
|
22
|
+
return false // Stop iteration after getting one value
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const next = (): [V | undefined, boolean] => {
|
|
26
|
+
if (done) {
|
|
27
|
+
return [undefined, false]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (hasNext) {
|
|
31
|
+
const value = nextValue
|
|
32
|
+
hasNext = false
|
|
33
|
+
nextValue = undefined
|
|
34
|
+
return [value, true]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Try to get next value
|
|
38
|
+
seq(function (value: V): boolean {
|
|
39
|
+
nextValue = value
|
|
40
|
+
hasNext = true
|
|
41
|
+
return false // Stop after getting one value
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
if (hasNext) {
|
|
45
|
+
const value = nextValue
|
|
46
|
+
hasNext = false
|
|
47
|
+
nextValue = undefined
|
|
48
|
+
return [value, true]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
done = true
|
|
52
|
+
return [undefined, false]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const stop = (): void => {
|
|
56
|
+
done = true
|
|
57
|
+
hasNext = false
|
|
58
|
+
nextValue = undefined
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return [next, stop]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Pull2 converts the "push-style" iterator sequence seq into a "pull-style" iterator
|
|
65
|
+
// Returns a function that returns the next key-value pair and a boolean indicating if iteration should continue
|
|
66
|
+
export function Pull2<K, V>(
|
|
67
|
+
seq: Seq2<K, V>,
|
|
68
|
+
): [() => [K | undefined, V | undefined, boolean], () => void] {
|
|
69
|
+
let done = false
|
|
70
|
+
let nextKey: K | undefined
|
|
71
|
+
let nextValue: V | undefined
|
|
72
|
+
let hasNext = false
|
|
73
|
+
|
|
74
|
+
const next = (): [K | undefined, V | undefined, boolean] => {
|
|
75
|
+
if (done) {
|
|
76
|
+
return [undefined, undefined, false]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (hasNext) {
|
|
80
|
+
const key = nextKey
|
|
81
|
+
const value = nextValue
|
|
82
|
+
hasNext = false
|
|
83
|
+
nextKey = undefined
|
|
84
|
+
nextValue = undefined
|
|
85
|
+
return [key, value, true]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Try to get next value
|
|
89
|
+
seq(function (key: K, value: V): boolean {
|
|
90
|
+
nextKey = key
|
|
91
|
+
nextValue = value
|
|
92
|
+
hasNext = true
|
|
93
|
+
return false // Stop after getting one value
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
if (hasNext) {
|
|
97
|
+
const key = nextKey
|
|
98
|
+
const value = nextValue
|
|
99
|
+
hasNext = false
|
|
100
|
+
nextKey = undefined
|
|
101
|
+
nextValue = undefined
|
|
102
|
+
return [key, value, true]
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
done = true
|
|
106
|
+
return [undefined, undefined, false]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const stop = (): void => {
|
|
110
|
+
done = true
|
|
111
|
+
hasNext = false
|
|
112
|
+
nextKey = undefined
|
|
113
|
+
nextValue = undefined
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return [next, stop]
|
|
117
|
+
}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
// Minimal stub for math/bits package
|
|
2
|
+
// This replaces the auto-generated version that has TypeScript syntax errors
|
|
3
|
+
|
|
4
|
+
// UintSize is the size of a uint in bits
|
|
5
|
+
export const UintSize = 32 // Assuming 32-bit for JavaScript numbers
|
|
6
|
+
|
|
7
|
+
// --- Leading zeros ---
|
|
8
|
+
export function LeadingZeros(x: number): number {
|
|
9
|
+
return Math.clz32(x >>> 0)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function LeadingZeros8(x: number): number {
|
|
13
|
+
return Math.clz32((x & 0xff) << 24)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function LeadingZeros16(x: number): number {
|
|
17
|
+
return Math.clz32((x & 0xffff) << 16)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function LeadingZeros32(x: number): number {
|
|
21
|
+
return Math.clz32(x >>> 0)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function LeadingZeros64(x: bigint): number {
|
|
25
|
+
// For 64-bit, we need to handle it differently
|
|
26
|
+
if (x === 0n) return 64
|
|
27
|
+
let count = 0
|
|
28
|
+
let mask = 1n << 63n
|
|
29
|
+
while ((x & mask) === 0n && count < 64) {
|
|
30
|
+
count++
|
|
31
|
+
mask >>= 1n
|
|
32
|
+
}
|
|
33
|
+
return count
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// --- Trailing zeros ---
|
|
37
|
+
export function TrailingZeros(x: number): number {
|
|
38
|
+
if (x === 0) return UintSize
|
|
39
|
+
return TrailingZeros32(x)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function TrailingZeros8(x: number): number {
|
|
43
|
+
if (x === 0) return 8
|
|
44
|
+
return Math.min(8, TrailingZeros32(x))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function TrailingZeros16(x: number): number {
|
|
48
|
+
if (x === 0) return 16
|
|
49
|
+
return Math.min(16, TrailingZeros32(x))
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function TrailingZeros32(x: number): number {
|
|
53
|
+
if (x === 0) return 32
|
|
54
|
+
let count = 0
|
|
55
|
+
while ((x & 1) === 0) {
|
|
56
|
+
count++
|
|
57
|
+
x >>>= 1
|
|
58
|
+
}
|
|
59
|
+
return count
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function TrailingZeros64(x: bigint): number {
|
|
63
|
+
if (x === 0n) return 64
|
|
64
|
+
let count = 0
|
|
65
|
+
while ((x & 1n) === 0n && count < 64) {
|
|
66
|
+
count++
|
|
67
|
+
x >>= 1n
|
|
68
|
+
}
|
|
69
|
+
return count
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// --- Ones count ---
|
|
73
|
+
export function OnesCount(x: number): number {
|
|
74
|
+
return OnesCount32(x)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function OnesCount8(x: number): number {
|
|
78
|
+
return OnesCount32(x & 0xff)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function OnesCount16(x: number): number {
|
|
82
|
+
return OnesCount32(x & 0xffff)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function OnesCount32(x: number): number {
|
|
86
|
+
// Brian Kernighan's algorithm
|
|
87
|
+
let count = 0
|
|
88
|
+
x = x >>> 0 // Ensure unsigned
|
|
89
|
+
while (x) {
|
|
90
|
+
count++
|
|
91
|
+
x &= x - 1
|
|
92
|
+
}
|
|
93
|
+
return count
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function OnesCount64(x: bigint): number {
|
|
97
|
+
let count = 0
|
|
98
|
+
while (x > 0n) {
|
|
99
|
+
count++
|
|
100
|
+
x &= x - 1n
|
|
101
|
+
}
|
|
102
|
+
return count
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// --- Rotate left ---
|
|
106
|
+
export function RotateLeft(x: number, k: number): number {
|
|
107
|
+
return RotateLeft32(x, k)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function RotateLeft8(x: number, k: number): number {
|
|
111
|
+
const n = 8
|
|
112
|
+
k = k % n
|
|
113
|
+
x = x & 0xff
|
|
114
|
+
return ((x << k) | (x >> (n - k))) & 0xff
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function RotateLeft16(x: number, k: number): number {
|
|
118
|
+
const n = 16
|
|
119
|
+
k = k % n
|
|
120
|
+
x = x & 0xffff
|
|
121
|
+
return ((x << k) | (x >> (n - k))) & 0xffff
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function RotateLeft32(x: number, k: number): number {
|
|
125
|
+
const n = 32
|
|
126
|
+
k = k % n
|
|
127
|
+
x = x >>> 0 // Ensure unsigned
|
|
128
|
+
return ((x << k) | (x >>> (n - k))) >>> 0
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function RotateLeft64(x: bigint, k: number): bigint {
|
|
132
|
+
const n = 64
|
|
133
|
+
k = k % n
|
|
134
|
+
const mask = (1n << 64n) - 1n
|
|
135
|
+
x = x & mask
|
|
136
|
+
return ((x << BigInt(k)) | (x >> BigInt(n - k))) & mask
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// --- Reverse ---
|
|
140
|
+
export function Reverse(x: number): number {
|
|
141
|
+
return Reverse32(x)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function Reverse8(x: number): number {
|
|
145
|
+
x = x & 0xff
|
|
146
|
+
x = ((x & 0xf0) >> 4) | ((x & 0x0f) << 4)
|
|
147
|
+
x = ((x & 0xcc) >> 2) | ((x & 0x33) << 2)
|
|
148
|
+
x = ((x & 0xaa) >> 1) | ((x & 0x55) << 1)
|
|
149
|
+
return x
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function Reverse16(x: number): number {
|
|
153
|
+
x = x & 0xffff
|
|
154
|
+
x = ((x & 0xff00) >> 8) | ((x & 0x00ff) << 8)
|
|
155
|
+
x = ((x & 0xf0f0) >> 4) | ((x & 0x0f0f) << 4)
|
|
156
|
+
x = ((x & 0xcccc) >> 2) | ((x & 0x3333) << 2)
|
|
157
|
+
x = ((x & 0xaaaa) >> 1) | ((x & 0x5555) << 1)
|
|
158
|
+
return x
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function Reverse32(x: number): number {
|
|
162
|
+
x = x >>> 0 // Ensure unsigned
|
|
163
|
+
x = ((x & 0xffff0000) >>> 16) | ((x & 0x0000ffff) << 16)
|
|
164
|
+
x = ((x & 0xff00ff00) >>> 8) | ((x & 0x00ff00ff) << 8)
|
|
165
|
+
x = ((x & 0xf0f0f0f0) >>> 4) | ((x & 0x0f0f0f0f) << 4)
|
|
166
|
+
x = ((x & 0xcccccccc) >>> 2) | ((x & 0x33333333) << 2)
|
|
167
|
+
x = ((x & 0xaaaaaaaa) >>> 1) | ((x & 0x55555555) << 1)
|
|
168
|
+
return x >>> 0
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function Reverse64(x: bigint): bigint {
|
|
172
|
+
// Implement 64-bit reverse using similar bit manipulation
|
|
173
|
+
const mask = (1n << 64n) - 1n
|
|
174
|
+
x = x & mask
|
|
175
|
+
|
|
176
|
+
// Swap 32-bit halves
|
|
177
|
+
x = ((x & 0xffffffff00000000n) >> 32n) | ((x & 0x00000000ffffffffn) << 32n)
|
|
178
|
+
// Swap 16-bit chunks
|
|
179
|
+
x = ((x & 0xffff0000ffff0000n) >> 16n) | ((x & 0x0000ffff0000ffffn) << 16n)
|
|
180
|
+
// Swap 8-bit chunks
|
|
181
|
+
x = ((x & 0xff00ff00ff00ff00n) >> 8n) | ((x & 0x00ff00ff00ff00ffn) << 8n)
|
|
182
|
+
// Swap 4-bit chunks
|
|
183
|
+
x = ((x & 0xf0f0f0f0f0f0f0f0n) >> 4n) | ((x & 0x0f0f0f0f0f0f0f0fn) << 4n)
|
|
184
|
+
// Swap 2-bit chunks
|
|
185
|
+
x = ((x & 0xccccccccccccccccn) >> 2n) | ((x & 0x3333333333333333n) << 2n)
|
|
186
|
+
// Swap 1-bit chunks
|
|
187
|
+
x = ((x & 0xaaaaaaaaaaaaaaaan) >> 1n) | ((x & 0x5555555555555555n) << 1n)
|
|
188
|
+
|
|
189
|
+
return x & mask
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// --- ReverseBytes ---
|
|
193
|
+
export function ReverseBytes(x: number): number {
|
|
194
|
+
return ReverseBytes32(x)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function ReverseBytes16(x: number): number {
|
|
198
|
+
return ((x & 0xff) << 8) | ((x & 0xff00) >> 8)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function ReverseBytes32(x: number): number {
|
|
202
|
+
x = x >>> 0 // Ensure unsigned
|
|
203
|
+
return (
|
|
204
|
+
(((x & 0xff) << 24) |
|
|
205
|
+
((x & 0xff00) << 8) |
|
|
206
|
+
((x & 0xff0000) >> 8) |
|
|
207
|
+
((x & 0xff000000) >>> 24)) >>>
|
|
208
|
+
0
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function ReverseBytes64(x: bigint): bigint {
|
|
213
|
+
const mask = (1n << 64n) - 1n
|
|
214
|
+
x = x & mask
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
(((x & 0xffn) << 56n) |
|
|
218
|
+
((x & 0xff00n) << 40n) |
|
|
219
|
+
((x & 0xff0000n) << 24n) |
|
|
220
|
+
((x & 0xff000000n) << 8n) |
|
|
221
|
+
((x & 0xff00000000n) >> 8n) |
|
|
222
|
+
((x & 0xff0000000000n) >> 24n) |
|
|
223
|
+
((x & 0xff000000000000n) >> 40n) |
|
|
224
|
+
((x & 0xff00000000000000n) >> 56n)) &
|
|
225
|
+
mask
|
|
226
|
+
)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// --- Len ---
|
|
230
|
+
export function Len(x: number): number {
|
|
231
|
+
return Len32(x)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export function Len8(x: number): number {
|
|
235
|
+
return 8 - LeadingZeros8(x)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function Len16(x: number): number {
|
|
239
|
+
return 16 - LeadingZeros16(x)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function Len32(x: number): number {
|
|
243
|
+
return 32 - LeadingZeros32(x)
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function Len64(x: bigint): number {
|
|
247
|
+
return 64 - LeadingZeros64(x)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// --- Multiplication functions ---
|
|
251
|
+
export function Mul(x: number, y: number): [number, number] {
|
|
252
|
+
return Mul32(x, y)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export function Mul32(x: number, y: number): [number, number] {
|
|
256
|
+
// For 32-bit multiplication, we can use JavaScript's number precision
|
|
257
|
+
const result = (x >>> 0) * (y >>> 0)
|
|
258
|
+
const hi = Math.floor(result / 0x100000000) >>> 0
|
|
259
|
+
const lo = result >>> 0
|
|
260
|
+
return [hi, lo]
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export function Mul64(x: bigint, y: bigint): [bigint, bigint] {
|
|
264
|
+
const mask32 = 0xffffffffn
|
|
265
|
+
|
|
266
|
+
// Split into 32-bit parts
|
|
267
|
+
const x0 = x & mask32
|
|
268
|
+
const x1 = x >> 32n
|
|
269
|
+
const y0 = y & mask32
|
|
270
|
+
const y1 = y >> 32n
|
|
271
|
+
|
|
272
|
+
// Multiply parts
|
|
273
|
+
const p00 = x0 * y0
|
|
274
|
+
const p01 = x0 * y1
|
|
275
|
+
const p10 = x1 * y0
|
|
276
|
+
const p11 = x1 * y1
|
|
277
|
+
|
|
278
|
+
// Combine results
|
|
279
|
+
const lo = p00 + ((p01 + p10) << 32n)
|
|
280
|
+
const hi = p11 + ((p01 + p10) >> 32n) + (lo < p00 ? 1n : 0n)
|
|
281
|
+
|
|
282
|
+
return [hi, lo]
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// --- Division functions ---
|
|
286
|
+
export function Div(hi: number, lo: number, y: number): [number, number] {
|
|
287
|
+
return Div32(hi, lo, y)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function Div32(hi: number, lo: number, y: number): [number, number] {
|
|
291
|
+
if (y === 0) {
|
|
292
|
+
throw new Error('division by zero')
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Combine hi and lo into a 64-bit value using BigInt for precision
|
|
296
|
+
const dividend = (BigInt(hi >>> 0) << 32n) | BigInt(lo >>> 0)
|
|
297
|
+
const divisor = BigInt(y >>> 0)
|
|
298
|
+
|
|
299
|
+
const quotient = dividend / divisor
|
|
300
|
+
const remainder = dividend % divisor
|
|
301
|
+
|
|
302
|
+
return [Number(quotient), Number(remainder)]
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export function Div64(hi: bigint, lo: bigint, y: bigint): [bigint, bigint] {
|
|
306
|
+
if (y === 0n) {
|
|
307
|
+
throw new Error('division by zero')
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Combine hi and lo into a 128-bit value (simulated)
|
|
311
|
+
// For simplicity, we'll use a basic implementation
|
|
312
|
+
const dividend = (hi << 64n) | lo
|
|
313
|
+
const quotient = dividend / y
|
|
314
|
+
const remainder = dividend % y
|
|
315
|
+
|
|
316
|
+
return [quotient, remainder]
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// --- Add and Sub with carry ---
|
|
320
|
+
export function Add(x: number, y: number, carry: number): [number, number] {
|
|
321
|
+
return Add32(x, y, carry)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export function Add32(x: number, y: number, carry: number): [number, number] {
|
|
325
|
+
const sum = (x >>> 0) + (y >>> 0) + (carry >>> 0)
|
|
326
|
+
const result = sum >>> 0
|
|
327
|
+
const carryOut = sum > 0xffffffff ? 1 : 0
|
|
328
|
+
return [result, carryOut]
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export function Add64(x: bigint, y: bigint, carry: bigint): [bigint, bigint] {
|
|
332
|
+
const mask = (1n << 64n) - 1n
|
|
333
|
+
const sum = (x & mask) + (y & mask) + (carry & mask)
|
|
334
|
+
const result = sum & mask
|
|
335
|
+
const carryOut = sum > mask ? 1n : 0n
|
|
336
|
+
return [result, carryOut]
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export function Sub(x: number, y: number, borrow: number): [number, number] {
|
|
340
|
+
return Sub32(x, y, borrow)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export function Sub32(x: number, y: number, borrow: number): [number, number] {
|
|
344
|
+
const diff = (x >>> 0) - (y >>> 0) - (borrow >>> 0)
|
|
345
|
+
const result = diff >>> 0
|
|
346
|
+
const borrowOut = diff < 0 ? 1 : 0
|
|
347
|
+
return [result, borrowOut]
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export function Sub64(x: bigint, y: bigint, borrow: bigint): [bigint, bigint] {
|
|
351
|
+
const mask = (1n << 64n) - 1n
|
|
352
|
+
const diff = (x & mask) - (y & mask) - (borrow & mask)
|
|
353
|
+
const result = diff & mask
|
|
354
|
+
const borrowOut = diff < 0n ? 1n : 0n
|
|
355
|
+
return [result, borrowOut]
|
|
356
|
+
}
|