@shd101wyy/yo 0.1.25 → 0.1.27
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/.github/skills/yo-async-effects/SKILL.md +4 -4
- package/.github/skills/yo-async-effects/async-effects-recipes.md +40 -40
- package/.github/skills/yo-core-patterns/SKILL.md +1 -1
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +30 -26
- package/.github/skills/yo-project-workflow/SKILL.md +6 -3
- package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +34 -11
- package/.github/skills/yo-syntax/SKILL.md +7 -6
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +78 -60
- package/.github/skills/yo-wasm-integration/wasm-integration-cheatsheet.md +3 -3
- package/README.md +10 -8
- package/out/cjs/index.cjs +583 -567
- package/out/cjs/yo-cli.cjs +664 -632
- package/out/cjs/yo-lsp.cjs +510 -485
- package/out/esm/index.mjs +538 -522
- package/out/types/src/codegen/codegen-c.d.ts +2 -2
- package/out/types/src/codegen/functions/collection.d.ts +2 -2
- package/out/types/src/codegen/functions/context.d.ts +3 -2
- package/out/types/src/codegen/types/collection.d.ts +2 -2
- package/out/types/src/codegen/utils/index.d.ts +3 -1
- package/out/types/src/doc/builder.d.ts +2 -2
- package/out/types/src/evaluator/calls/closure-type.d.ts +2 -2
- package/out/types/src/evaluator/calls/record-type.d.ts +11 -0
- package/out/types/src/evaluator/context.d.ts +8 -9
- package/out/types/src/evaluator/index.d.ts +3 -3
- package/out/types/src/evaluator/types/record.d.ts +14 -0
- package/out/types/src/evaluator/types/validation.d.ts +2 -2
- package/out/types/src/evaluator/values/anonymous-module.d.ts +5 -5
- package/out/types/src/evaluator/values/impl.d.ts +1 -1
- package/out/types/src/expr.d.ts +1 -4
- package/out/types/src/formatter.d.ts +11 -0
- package/out/types/src/function-value.d.ts +1 -1
- package/out/types/src/lsp/document-manager.d.ts +1 -1
- package/out/types/src/lsp/formatting.d.ts +2 -0
- package/out/types/src/module-manager.d.ts +3 -3
- package/out/types/src/tests/formatter.test.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +3 -4
- package/out/types/src/types/definitions.d.ts +8 -19
- package/out/types/src/types/guards.d.ts +3 -3
- package/out/types/src/types/tags.d.ts +0 -1
- package/out/types/src/types/utils.d.ts +1 -1
- package/out/types/src/value-tag.d.ts +0 -1
- package/out/types/src/value.d.ts +6 -13
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/std/alg/hash.yo +13 -21
- package/std/allocator.yo +25 -40
- package/std/async.yo +3 -7
- package/std/build.yo +105 -151
- package/std/cli/arg_parser.yo +184 -169
- package/std/collections/array_list.yo +350 -314
- package/std/collections/btree_map.yo +142 -131
- package/std/collections/deque.yo +132 -128
- package/std/collections/hash_map.yo +542 -566
- package/std/collections/hash_set.yo +623 -687
- package/std/collections/linked_list.yo +275 -293
- package/std/collections/ordered_map.yo +113 -85
- package/std/collections/priority_queue.yo +73 -73
- package/std/crypto/md5.yo +191 -95
- package/std/crypto/random.yo +56 -64
- package/std/crypto/sha256.yo +151 -107
- package/std/encoding/base64.yo +87 -81
- package/std/encoding/hex.yo +43 -50
- package/std/encoding/html.yo +56 -81
- package/std/encoding/html_char_utils.yo +7 -13
- package/std/encoding/html_entities.yo +2248 -2253
- package/std/encoding/json.yo +316 -224
- package/std/encoding/punycode.yo +86 -116
- package/std/encoding/toml.yo +67 -66
- package/std/encoding/utf16.yo +37 -44
- package/std/env.yo +62 -91
- package/std/error.yo +12 -20
- package/std/fmt/display.yo +5 -9
- package/std/fmt/index.yo +8 -14
- package/std/fmt/to_string.yo +330 -315
- package/std/fmt/writer.yo +58 -87
- package/std/fs/dir.yo +83 -102
- package/std/fs/file.yo +147 -180
- package/std/fs/metadata.yo +45 -78
- package/std/fs/temp.yo +55 -65
- package/std/fs/types.yo +27 -40
- package/std/fs/walker.yo +53 -68
- package/std/gc.yo +5 -8
- package/std/glob.yo +30 -43
- package/std/http/client.yo +107 -120
- package/std/http/http.yo +106 -96
- package/std/http/index.yo +4 -6
- package/std/imm/list.yo +88 -93
- package/std/imm/map.yo +528 -464
- package/std/imm/set.yo +52 -57
- package/std/imm/sorted_map.yo +340 -286
- package/std/imm/sorted_set.yo +57 -63
- package/std/imm/string.yo +404 -345
- package/std/imm/vec.yo +173 -181
- package/std/io/reader.yo +3 -6
- package/std/io/writer.yo +4 -8
- package/std/libc/assert.yo +5 -9
- package/std/libc/ctype.yo +32 -22
- package/std/libc/dirent.yo +26 -25
- package/std/libc/errno.yo +164 -90
- package/std/libc/fcntl.yo +52 -45
- package/std/libc/float.yo +66 -44
- package/std/libc/limits.yo +42 -33
- package/std/libc/math.yo +53 -82
- package/std/libc/signal.yo +72 -47
- package/std/libc/stdatomic.yo +217 -188
- package/std/libc/stdint.yo +5 -29
- package/std/libc/stdio.yo +5 -29
- package/std/libc/stdlib.yo +32 -39
- package/std/libc/string.yo +5 -23
- package/std/libc/sys/stat.yo +58 -56
- package/std/libc/time.yo +5 -19
- package/std/libc/unistd.yo +5 -20
- package/std/libc/wctype.yo +6 -9
- package/std/libc/windows.yo +26 -30
- package/std/log.yo +41 -55
- package/std/net/addr.yo +102 -97
- package/std/net/dns.yo +27 -28
- package/std/net/errors.yo +50 -49
- package/std/net/tcp.yo +113 -124
- package/std/net/udp.yo +55 -66
- package/std/os/env.yo +35 -33
- package/std/os/signal.yo +15 -25
- package/std/path.yo +276 -311
- package/std/prelude.yo +6316 -4333
- package/std/process/command.yo +87 -103
- package/std/process/index.yo +12 -31
- package/std/regex/compiler.yo +196 -95
- package/std/regex/flags.yo +58 -39
- package/std/regex/index.yo +157 -173
- package/std/regex/match.yo +20 -31
- package/std/regex/node.yo +134 -152
- package/std/regex/parser.yo +283 -259
- package/std/regex/unicode.yo +172 -202
- package/std/regex/vm.yo +155 -171
- package/std/string/index.yo +5 -7
- package/std/string/rune.yo +45 -55
- package/std/string/string.yo +937 -964
- package/std/string/string_builder.yo +94 -104
- package/std/string/unicode.yo +46 -64
- package/std/sync/channel.yo +72 -73
- package/std/sync/cond.yo +31 -36
- package/std/sync/mutex.yo +30 -32
- package/std/sync/once.yo +13 -16
- package/std/sync/rwlock.yo +26 -31
- package/std/sync/waitgroup.yo +20 -25
- package/std/sys/advise.yo +16 -24
- package/std/sys/bufio/buf_reader.yo +77 -93
- package/std/sys/bufio/buf_writer.yo +52 -65
- package/std/sys/clock.yo +4 -9
- package/std/sys/constants.yo +77 -61
- package/std/sys/copy.yo +4 -10
- package/std/sys/dir.yo +26 -43
- package/std/sys/dns.yo +41 -61
- package/std/sys/errors.yo +95 -103
- package/std/sys/events.yo +45 -57
- package/std/sys/externs.yo +319 -267
- package/std/sys/fallocate.yo +7 -11
- package/std/sys/fcntl.yo +14 -22
- package/std/sys/file.yo +26 -40
- package/std/sys/future.yo +5 -8
- package/std/sys/iov.yo +12 -25
- package/std/sys/lock.yo +12 -13
- package/std/sys/mmap.yo +38 -43
- package/std/sys/path.yo +3 -8
- package/std/sys/perm.yo +7 -21
- package/std/sys/pipe.yo +5 -12
- package/std/sys/process.yo +23 -29
- package/std/sys/seek.yo +10 -12
- package/std/sys/signal.yo +7 -13
- package/std/sys/signals.yo +52 -35
- package/std/sys/socket.yo +63 -58
- package/std/sys/socketpair.yo +3 -6
- package/std/sys/sockinfo.yo +11 -20
- package/std/sys/statfs.yo +11 -34
- package/std/sys/statx.yo +25 -52
- package/std/sys/sysinfo.yo +15 -20
- package/std/sys/tcp.yo +62 -92
- package/std/sys/temp.yo +5 -9
- package/std/sys/time.yo +5 -15
- package/std/sys/timer.yo +6 -11
- package/std/sys/tty.yo +10 -18
- package/std/sys/udp.yo +22 -39
- package/std/sys/umask.yo +3 -6
- package/std/sys/unix.yo +33 -52
- package/std/testing/bench.yo +49 -52
- package/std/thread.yo +10 -15
- package/std/time/datetime.yo +105 -89
- package/std/time/duration.yo +43 -56
- package/std/time/instant.yo +13 -18
- package/std/time/sleep.yo +5 -9
- package/std/url/index.yo +184 -209
- package/std/worker.yo +6 -10
- package/out/types/src/evaluator/calls/module-type.d.ts +0 -11
- package/out/types/src/evaluator/types/module.d.ts +0 -19
|
@@ -32,44 +32,41 @@
|
|
|
32
32
|
//! );
|
|
33
33
|
//! };
|
|
34
34
|
//! ```
|
|
35
|
-
|
|
36
|
-
open
|
|
37
|
-
open import "./hash_map";
|
|
38
|
-
|
|
35
|
+
open(import("./array_list"));
|
|
36
|
+
open(import("./hash_map"));
|
|
39
37
|
/// Ordered map preserving insertion order of keys.
|
|
40
38
|
/// Keys must implement `Eq` and `Hash`.
|
|
41
|
-
OrderedMap :: (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
OrderedMap :: (
|
|
40
|
+
fn(
|
|
41
|
+
comptime(K) : Type,
|
|
42
|
+
comptime(V) : Type,
|
|
43
|
+
where(K <: (Eq(K), Hash))
|
|
44
|
+
) -> comptime(Type)
|
|
45
|
+
)(
|
|
46
46
|
object(
|
|
47
47
|
_map : HashMap(K, V),
|
|
48
48
|
_order : ArrayList(K)
|
|
49
49
|
)
|
|
50
|
-
;
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
);
|
|
51
|
+
impl(
|
|
52
|
+
forall(K : Type, V : Type),
|
|
53
|
+
where(K <: (Eq(K), Hash)),
|
|
54
|
+
OrderedMap(K, V),
|
|
53
55
|
/// Create an empty `OrderedMap`.
|
|
54
56
|
new : (fn() -> Self)(
|
|
55
57
|
Self(
|
|
56
|
-
_map: HashMap(K, V).new(),
|
|
57
|
-
_order: ArrayList(K).new()
|
|
58
|
+
_map : HashMap(K, V).new(),
|
|
59
|
+
_order : ArrayList(K).new()
|
|
58
60
|
)
|
|
59
61
|
),
|
|
60
|
-
|
|
61
62
|
/// Number of entries.
|
|
62
63
|
len : (fn(self : Self) -> usize)(self._map.len()),
|
|
63
|
-
|
|
64
64
|
/// Whether the map is empty.
|
|
65
65
|
is_empty : (fn(self : Self) -> bool)(self._map.is_empty()),
|
|
66
|
-
|
|
67
66
|
/// Returns `true` if `key` is present.
|
|
68
67
|
contains_key : (fn(self : Self, key : K) -> bool)(self._map.contains_key(key)),
|
|
69
|
-
|
|
70
68
|
/// Returns the value for `key`, or `.None`.
|
|
71
69
|
get : (fn(self : Self, key : K) -> Option(V))(self._map.get(key)),
|
|
72
|
-
|
|
73
70
|
/// Insert or update `key -> value`.
|
|
74
71
|
///
|
|
75
72
|
/// - For a new key, appends `key` to the insertion order.
|
|
@@ -81,164 +78,195 @@ impl(forall(K : Type, V : Type), where(K <: (Eq(K), Hash)), OrderedMap(K, V),
|
|
|
81
78
|
is_new := !(self._map.contains_key(key));
|
|
82
79
|
result := self._map.set(key, value);
|
|
83
80
|
cond(
|
|
84
|
-
is_new => match(
|
|
85
|
-
|
|
81
|
+
is_new => match(
|
|
82
|
+
result,
|
|
83
|
+
.Ok(_) => {
|
|
84
|
+
self._order.push(key);
|
|
85
|
+
},
|
|
86
86
|
.Err(_) => ()
|
|
87
87
|
),
|
|
88
88
|
true => ()
|
|
89
89
|
);
|
|
90
|
-
return
|
|
90
|
+
return(result);
|
|
91
91
|
}),
|
|
92
|
-
|
|
93
92
|
/// Remove `key`. Returns the removed value or `.None`.
|
|
94
93
|
/// O(n) — rebuilds the key order list to drop the removed key.
|
|
95
94
|
remove : (fn(self : Self, key : K) -> Option(V))({
|
|
96
95
|
removed := self._map.remove(key);
|
|
97
|
-
match(
|
|
96
|
+
match(
|
|
97
|
+
removed,
|
|
98
98
|
.Some(_) => {
|
|
99
99
|
new_order := ArrayList(K).new();
|
|
100
100
|
i := usize(0);
|
|
101
101
|
n := self._order.len();
|
|
102
|
-
while
|
|
103
|
-
match(
|
|
102
|
+
while(i < n, i = (i + usize(1)), {
|
|
103
|
+
match(
|
|
104
|
+
self._order.get(i),
|
|
104
105
|
.Some(k) => {
|
|
105
106
|
cond(
|
|
106
107
|
(k == key) => (),
|
|
107
|
-
true => {
|
|
108
|
+
true => {
|
|
109
|
+
new_order.push(k);
|
|
110
|
+
}
|
|
108
111
|
);
|
|
109
112
|
},
|
|
110
113
|
.None => ()
|
|
111
114
|
);
|
|
112
|
-
};
|
|
115
|
+
});
|
|
113
116
|
self._order = new_order;
|
|
114
117
|
},
|
|
115
118
|
.None => ()
|
|
116
119
|
);
|
|
117
|
-
return
|
|
120
|
+
return(removed);
|
|
118
121
|
}),
|
|
119
|
-
|
|
120
122
|
/// Remove all entries.
|
|
121
123
|
clear : (fn(self : Self) -> unit)({
|
|
122
124
|
self._map.clear();
|
|
123
125
|
self._order = ArrayList(K).new();
|
|
124
126
|
})
|
|
125
127
|
);
|
|
126
|
-
|
|
127
128
|
/// Iterator over the keys of an `OrderedMap` in insertion order.
|
|
128
|
-
OrderedMapKeys :: (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
OrderedMapKeys :: (
|
|
130
|
+
fn(
|
|
131
|
+
comptime(K) : Type,
|
|
132
|
+
comptime(V) : Type,
|
|
133
|
+
where(K <: (Eq(K), Hash))
|
|
134
|
+
) -> comptime(Type)
|
|
135
|
+
)(
|
|
133
136
|
object(
|
|
134
137
|
_map : OrderedMap(K, V),
|
|
135
138
|
_index : usize
|
|
136
139
|
)
|
|
137
|
-
;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
+
);
|
|
141
|
+
impl(
|
|
142
|
+
forall(K : Type, V : Type),
|
|
143
|
+
where(K <: (Eq(K), Hash)),
|
|
144
|
+
OrderedMapKeys(K, V),
|
|
140
145
|
next : (fn(self : *(Self)) -> Option(K))({
|
|
141
146
|
cond(
|
|
142
|
-
(self._index >= self._map._order.len()) => {
|
|
147
|
+
(self._index >= self._map._order.len()) => {
|
|
148
|
+
return(.None);
|
|
149
|
+
},
|
|
143
150
|
true => ()
|
|
144
151
|
);
|
|
145
152
|
k := self._map._order.get(self._index);
|
|
146
153
|
self._index = (self._index + usize(1));
|
|
147
|
-
return
|
|
154
|
+
return(k);
|
|
148
155
|
})
|
|
149
156
|
);
|
|
150
|
-
|
|
151
157
|
/// Iterator over the values of an `OrderedMap` in insertion order.
|
|
152
|
-
OrderedMapValues :: (
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
OrderedMapValues :: (
|
|
159
|
+
fn(
|
|
160
|
+
comptime(K) : Type,
|
|
161
|
+
comptime(V) : Type,
|
|
162
|
+
where(K <: (Eq(K), Hash))
|
|
163
|
+
) -> comptime(Type)
|
|
164
|
+
)(
|
|
157
165
|
object(
|
|
158
166
|
_map : OrderedMap(K, V),
|
|
159
167
|
_index : usize
|
|
160
168
|
)
|
|
161
|
-
;
|
|
162
|
-
|
|
163
|
-
|
|
169
|
+
);
|
|
170
|
+
impl(
|
|
171
|
+
forall(K : Type, V : Type),
|
|
172
|
+
where(K <: (Eq(K), Hash)),
|
|
173
|
+
OrderedMapValues(K, V),
|
|
164
174
|
next : (fn(self : *(Self)) -> Option(V))({
|
|
165
175
|
cond(
|
|
166
|
-
(self._index >= self._map._order.len()) => {
|
|
176
|
+
(self._index >= self._map._order.len()) => {
|
|
177
|
+
return(.None);
|
|
178
|
+
},
|
|
167
179
|
true => ()
|
|
168
180
|
);
|
|
169
|
-
match(
|
|
181
|
+
match(
|
|
182
|
+
self._map._order.get(self._index),
|
|
170
183
|
.Some(k) => {
|
|
171
184
|
self._index = (self._index + usize(1));
|
|
172
|
-
return
|
|
185
|
+
return(self._map._map.get(k));
|
|
173
186
|
},
|
|
174
|
-
.None => {
|
|
187
|
+
.None => {
|
|
188
|
+
return(.None);
|
|
189
|
+
}
|
|
175
190
|
);
|
|
176
191
|
})
|
|
177
192
|
);
|
|
178
|
-
|
|
179
193
|
/// Key-value pair yielded by `OrderedMapIter`.
|
|
180
|
-
OrderedMapEntry :: (
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
)
|
|
194
|
+
OrderedMapEntry :: (
|
|
195
|
+
fn(
|
|
196
|
+
comptime(K) : Type,
|
|
197
|
+
comptime(V) : Type
|
|
198
|
+
) -> comptime(Type)
|
|
199
|
+
)(
|
|
184
200
|
struct(
|
|
185
201
|
key : K,
|
|
186
202
|
value : V
|
|
187
203
|
)
|
|
188
|
-
;
|
|
189
|
-
|
|
204
|
+
);
|
|
190
205
|
/// Iterator over `(key, value)` pairs of an `OrderedMap` in insertion order.
|
|
191
|
-
OrderedMapIter :: (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
206
|
+
OrderedMapIter :: (
|
|
207
|
+
fn(
|
|
208
|
+
comptime(K) : Type,
|
|
209
|
+
comptime(V) : Type,
|
|
210
|
+
where(K <: (Eq(K), Hash))
|
|
211
|
+
) -> comptime(Type)
|
|
212
|
+
)(
|
|
196
213
|
object(
|
|
197
214
|
_map : OrderedMap(K, V),
|
|
198
215
|
_index : usize
|
|
199
216
|
)
|
|
200
|
-
;
|
|
201
|
-
|
|
202
|
-
|
|
217
|
+
);
|
|
218
|
+
impl(
|
|
219
|
+
forall(K : Type, V : Type),
|
|
220
|
+
where(K <: (Eq(K), Hash)),
|
|
221
|
+
OrderedMapIter(K, V),
|
|
203
222
|
next : (fn(self : *(Self)) -> Option(OrderedMapEntry(K, V)))({
|
|
204
223
|
cond(
|
|
205
|
-
(self._index >= self._map._order.len()) => {
|
|
224
|
+
(self._index >= self._map._order.len()) => {
|
|
225
|
+
return(.None);
|
|
226
|
+
},
|
|
206
227
|
true => ()
|
|
207
228
|
);
|
|
208
|
-
match(
|
|
229
|
+
match(
|
|
230
|
+
self._map._order.get(self._index),
|
|
209
231
|
.Some(k) => {
|
|
210
232
|
self._index = (self._index + usize(1));
|
|
211
|
-
match(
|
|
212
|
-
.
|
|
213
|
-
.
|
|
233
|
+
match(
|
|
234
|
+
self._map._map.get(k),
|
|
235
|
+
.Some(v) => {
|
|
236
|
+
return(.Some(OrderedMapEntry(K, V)(key : k, value : v)));
|
|
237
|
+
},
|
|
238
|
+
.None => {
|
|
239
|
+
return(.None);
|
|
240
|
+
}
|
|
214
241
|
);
|
|
215
242
|
},
|
|
216
|
-
.None => {
|
|
243
|
+
.None => {
|
|
244
|
+
return(.None);
|
|
245
|
+
}
|
|
217
246
|
);
|
|
218
247
|
})
|
|
219
248
|
);
|
|
220
|
-
|
|
221
|
-
|
|
249
|
+
impl(
|
|
250
|
+
forall(K : Type, V : Type),
|
|
251
|
+
where(K <: (Eq(K), Hash)),
|
|
252
|
+
OrderedMap(K, V),
|
|
222
253
|
/// Iterator over keys in insertion order.
|
|
223
254
|
keys : (fn(self : Self) -> OrderedMapKeys(K, V))(
|
|
224
|
-
OrderedMapKeys(K, V)(_map: self, _index: usize(0))
|
|
255
|
+
OrderedMapKeys(K, V)(_map : self, _index : usize(0))
|
|
225
256
|
),
|
|
226
|
-
|
|
227
257
|
/// Iterator over values in insertion order.
|
|
228
258
|
values : (fn(self : Self) -> OrderedMapValues(K, V))(
|
|
229
|
-
OrderedMapValues(K, V)(_map: self, _index: usize(0))
|
|
259
|
+
OrderedMapValues(K, V)(_map : self, _index : usize(0))
|
|
230
260
|
),
|
|
231
|
-
|
|
232
261
|
/// Iterator over `(key, value)` pairs in insertion order.
|
|
233
262
|
iter : (fn(self : Self) -> OrderedMapIter(K, V))(
|
|
234
|
-
OrderedMapIter(K, V)(_map: self, _index: usize(0))
|
|
263
|
+
OrderedMapIter(K, V)(_map : self, _index : usize(0))
|
|
235
264
|
)
|
|
236
265
|
);
|
|
237
|
-
|
|
238
|
-
export
|
|
266
|
+
export(
|
|
239
267
|
OrderedMap,
|
|
240
268
|
OrderedMapEntry,
|
|
241
269
|
OrderedMapKeys,
|
|
242
270
|
OrderedMapValues,
|
|
243
271
|
OrderedMapIter
|
|
244
|
-
;
|
|
272
|
+
);
|
|
@@ -11,9 +11,7 @@
|
|
|
11
11
|
//! pq.push(3);
|
|
12
12
|
//! x := pq.pop().unwrap(); // 1
|
|
13
13
|
//! ```
|
|
14
|
-
|
|
15
|
-
{ ArrayList } :: import "./array_list";
|
|
16
|
-
|
|
14
|
+
{ ArrayList } :: import("./array_list");
|
|
17
15
|
/// Min-heap backed by an ArrayList.
|
|
18
16
|
/// Elements are ordered ascending (smallest first). Negate keys for max-heap behavior.
|
|
19
17
|
PriorityQueue :: (fn(comptime(T) : Type) -> comptime(Type))(
|
|
@@ -21,39 +19,36 @@ PriorityQueue :: (fn(comptime(T) : Type) -> comptime(Type))(
|
|
|
21
19
|
_data : ArrayList(T)
|
|
22
20
|
)
|
|
23
21
|
);
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
impl(
|
|
23
|
+
forall(T : Type),
|
|
24
|
+
PriorityQueue(T),
|
|
26
25
|
// Create an empty priority queue.
|
|
27
26
|
new : (fn() -> Self)(
|
|
28
|
-
Self(_data: ArrayList(T).new())
|
|
27
|
+
Self(_data : ArrayList(T).new())
|
|
29
28
|
),
|
|
30
|
-
|
|
31
29
|
// Number of elements.
|
|
32
|
-
len : (fn(self: Self) -> usize)(
|
|
30
|
+
len : (fn(self : Self) -> usize)(
|
|
33
31
|
self._data.len()
|
|
34
32
|
),
|
|
35
|
-
|
|
36
33
|
// True if empty.
|
|
37
|
-
is_empty : (fn(self: Self) -> bool)(
|
|
38
|
-
|
|
34
|
+
is_empty : (fn(self : Self) -> bool)(
|
|
35
|
+
self._data.len() == usize(0)
|
|
39
36
|
),
|
|
40
|
-
|
|
41
37
|
// Inspect the smallest element without removing it.
|
|
42
|
-
peek : (fn(self: Self) -> Option(T))(
|
|
38
|
+
peek : (fn(self : Self) -> Option(T))(
|
|
43
39
|
cond(
|
|
44
|
-
(self._data.len() == usize(0))
|
|
40
|
+
(self._data.len() == usize(0)) =>.None,
|
|
45
41
|
true => self._data.get(usize(0))
|
|
46
42
|
)
|
|
47
43
|
),
|
|
48
|
-
|
|
49
44
|
// Insert a new element.
|
|
50
|
-
push : (fn(self: Self, val: T, where(T <: Ord(T))) -> unit)({
|
|
45
|
+
push : (fn(self : Self, val : T, where(T <: Ord(T))) -> unit)({
|
|
51
46
|
self._data.push(val);
|
|
52
47
|
// Sift up
|
|
53
48
|
i := (self._data.len() - usize(1));
|
|
54
|
-
while
|
|
49
|
+
while(i > usize(0), {
|
|
55
50
|
parent := ((i - usize(1)) / usize(2));
|
|
56
|
-
child_val
|
|
51
|
+
child_val := self._data.get(i).unwrap();
|
|
57
52
|
parent_val := self._data.get(parent).unwrap();
|
|
58
53
|
cond(
|
|
59
54
|
(child_val < parent_val) => {
|
|
@@ -65,23 +60,22 @@ impl(forall(T : Type), PriorityQueue(T),
|
|
|
65
60
|
break;
|
|
66
61
|
}
|
|
67
62
|
);
|
|
68
|
-
};
|
|
63
|
+
});
|
|
69
64
|
}),
|
|
70
|
-
|
|
71
65
|
// Remove and return the smallest element.
|
|
72
|
-
pop : (fn(self: Self, where(T <: Ord(T))) -> Option(T))({
|
|
66
|
+
pop : (fn(self : Self, where(T <: Ord(T))) -> Option(T))({
|
|
73
67
|
n := self._data.len();
|
|
74
68
|
cond(
|
|
75
|
-
(n == usize(0))
|
|
69
|
+
(n == usize(0)) =>.None,
|
|
76
70
|
true => {
|
|
77
|
-
top
|
|
78
|
-
last := self._data.get(
|
|
71
|
+
top := self._data.get(usize(0)).unwrap();
|
|
72
|
+
last := self._data.get(n - usize(1)).unwrap();
|
|
79
73
|
&(self._data(usize(0))).* = last;
|
|
80
74
|
self._data.pop();
|
|
81
75
|
// Sift down
|
|
82
76
|
i := usize(0);
|
|
83
|
-
while
|
|
84
|
-
left
|
|
77
|
+
while(runtime(true), {
|
|
78
|
+
left := ((i * usize(2)) + usize(1));
|
|
85
79
|
right := ((i * usize(2)) + usize(2));
|
|
86
80
|
smallest := i;
|
|
87
81
|
new_n := self._data.len();
|
|
@@ -109,80 +103,86 @@ impl(forall(T : Type), PriorityQueue(T),
|
|
|
109
103
|
i = smallest;
|
|
110
104
|
}
|
|
111
105
|
);
|
|
112
|
-
};
|
|
106
|
+
});
|
|
113
107
|
.Some(top)
|
|
114
108
|
}
|
|
115
109
|
)
|
|
116
110
|
})
|
|
117
111
|
);
|
|
118
|
-
|
|
119
112
|
/**
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
113
|
+
* Value iterator for PriorityQueue - yields elements in heap (arbitrary) order
|
|
114
|
+
* Note: This iterates in internal storage order, NOT sorted order.
|
|
115
|
+
*/
|
|
123
116
|
PriorityQueueIter :: (fn(comptime(T) : Type) -> comptime(Type))(
|
|
124
117
|
struct(
|
|
125
|
-
_data
|
|
118
|
+
_data : ArrayList(T),
|
|
126
119
|
_index : usize
|
|
127
120
|
)
|
|
128
121
|
);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
122
|
+
impl(
|
|
123
|
+
forall(T : Type),
|
|
124
|
+
PriorityQueueIter(T),
|
|
125
|
+
Iterator(
|
|
126
|
+
Item : T,
|
|
127
|
+
next : (fn(self : *(Self)) -> Option(T))(
|
|
128
|
+
cond(
|
|
129
|
+
(self._index >= self._data.len()) =>.None,
|
|
130
|
+
true => {
|
|
131
|
+
value := self._data.get(self._index).unwrap();
|
|
132
|
+
self._index = (self._index + usize(1));
|
|
133
|
+
.Some(value)
|
|
134
|
+
}
|
|
135
|
+
)
|
|
140
136
|
)
|
|
141
137
|
)
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
138
|
+
);
|
|
139
|
+
impl(
|
|
140
|
+
forall(T : Type),
|
|
141
|
+
PriorityQueue(T),
|
|
145
142
|
into_iter : (fn(self : Self) -> PriorityQueueIter(T))(
|
|
146
|
-
PriorityQueueIter(T)(_data: self._data, _index: usize(0))
|
|
143
|
+
PriorityQueueIter(T)(_data : self._data, _index : usize(0))
|
|
147
144
|
)
|
|
148
145
|
);
|
|
149
|
-
|
|
150
146
|
/**
|
|
151
|
-
|
|
152
|
-
|
|
147
|
+
* Pointer iterator for PriorityQueue - yields pointers to elements in heap order
|
|
148
|
+
*/
|
|
153
149
|
PriorityQueueIterPtr :: (fn(comptime(T) : Type) -> comptime(Type))(
|
|
154
150
|
struct(
|
|
155
|
-
_data
|
|
151
|
+
_data : ArrayList(T),
|
|
156
152
|
_index : usize
|
|
157
153
|
)
|
|
158
154
|
);
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
self.
|
|
170
|
-
.Some(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
155
|
+
impl(
|
|
156
|
+
forall(T : Type),
|
|
157
|
+
PriorityQueueIterPtr(T),
|
|
158
|
+
Iterator(
|
|
159
|
+
Item : *(T),
|
|
160
|
+
next : (fn(self : *(Self)) -> Option(*(T)))(
|
|
161
|
+
cond(
|
|
162
|
+
(self._index >= self._data.len()) =>.None,
|
|
163
|
+
true =>
|
|
164
|
+
match(
|
|
165
|
+
self._data._ptr,
|
|
166
|
+
.Some(ptr) => {
|
|
167
|
+
element_ptr := (ptr &+ self._index);
|
|
168
|
+
self._index = (self._index + usize(1));
|
|
169
|
+
.Some(element_ptr)
|
|
170
|
+
},
|
|
171
|
+
.None =>.None
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
174
|
)
|
|
175
175
|
)
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
);
|
|
177
|
+
impl(
|
|
178
|
+
forall(T : Type),
|
|
179
|
+
PriorityQueue(T),
|
|
179
180
|
iter : (fn(self : *(Self)) -> PriorityQueueIterPtr(T))(
|
|
180
|
-
PriorityQueueIterPtr(T)(_data: self.*._data, _index: usize(0))
|
|
181
|
+
PriorityQueueIterPtr(T)(_data : self.*._data, _index : usize(0))
|
|
181
182
|
)
|
|
182
183
|
);
|
|
183
|
-
|
|
184
|
-
export
|
|
184
|
+
export(
|
|
185
185
|
PriorityQueue,
|
|
186
186
|
PriorityQueueIter,
|
|
187
187
|
PriorityQueueIterPtr
|
|
188
|
-
;
|
|
188
|
+
);
|