ic-mops 0.8.5 → 0.8.7
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/package.json +3 -1
- package/.mops/base@0.7.4/LICENSE +0 -208
- package/.mops/base@0.7.4/README.md +0 -64
- package/.mops/base@0.7.4/mops.toml +0 -5
- package/.mops/base@0.7.4/src/Array.mo +0 -686
- package/.mops/base@0.7.4/src/AssocList.mo +0 -203
- package/.mops/base@0.7.4/src/Blob.mo +0 -55
- package/.mops/base@0.7.4/src/Bool.mo +0 -44
- package/.mops/base@0.7.4/src/Buffer.mo +0 -1937
- package/.mops/base@0.7.4/src/CertifiedData.mo +0 -29
- package/.mops/base@0.7.4/src/Char.mo +0 -67
- package/.mops/base@0.7.4/src/Debug.mo +0 -15
- package/.mops/base@0.7.4/src/Deque.mo +0 -75
- package/.mops/base@0.7.4/src/Error.mo +0 -41
- package/.mops/base@0.7.4/src/ExperimentalCycles.mo +0 -51
- package/.mops/base@0.7.4/src/ExperimentalInternetComputer.mo +0 -36
- package/.mops/base@0.7.4/src/ExperimentalStableMemory.mo +0 -121
- package/.mops/base@0.7.4/src/Float.mo +0 -150
- package/.mops/base@0.7.4/src/Func.mo +0 -38
- package/.mops/base@0.7.4/src/Hash.mo +0 -83
- package/.mops/base@0.7.4/src/HashMap.mo +0 -229
- package/.mops/base@0.7.4/src/Heap.mo +0 -113
- package/.mops/base@0.7.4/src/Int.mo +0 -150
- package/.mops/base@0.7.4/src/Int16.mo +0 -159
- package/.mops/base@0.7.4/src/Int32.mo +0 -160
- package/.mops/base@0.7.4/src/Int64.mo +0 -161
- package/.mops/base@0.7.4/src/Int8.mo +0 -160
- package/.mops/base@0.7.4/src/Iter.mo +0 -220
- package/.mops/base@0.7.4/src/IterType.mo +0 -7
- package/.mops/base@0.7.4/src/List.mo +0 -433
- package/.mops/base@0.7.4/src/Nat.mo +0 -75
- package/.mops/base@0.7.4/src/Nat16.mo +0 -146
- package/.mops/base@0.7.4/src/Nat32.mo +0 -146
- package/.mops/base@0.7.4/src/Nat64.mo +0 -146
- package/.mops/base@0.7.4/src/Nat8.mo +0 -146
- package/.mops/base@0.7.4/src/None.mo +0 -19
- package/.mops/base@0.7.4/src/Option.mo +0 -160
- package/.mops/base@0.7.4/src/Order.mo +0 -46
- package/.mops/base@0.7.4/src/Prelude.mo +0 -33
- package/.mops/base@0.7.4/src/Principal.mo +0 -58
- package/.mops/base@0.7.4/src/RBTree.mo +0 -218
- package/.mops/base@0.7.4/src/Random.mo +0 -188
- package/.mops/base@0.7.4/src/Result.mo +0 -210
- package/.mops/base@0.7.4/src/Stack.mo +0 -40
- package/.mops/base@0.7.4/src/Text.mo +0 -615
- package/.mops/base@0.7.4/src/Time.mo +0 -37
- package/.mops/base@0.7.4/src/Trie.mo +0 -1200
- package/.mops/base@0.7.4/src/TrieMap.mo +0 -180
- package/.mops/base@0.7.4/src/TrieSet.mo +0 -97
- package/.mops/base@0.8.3/LICENSE +0 -208
- package/.mops/base@0.8.3/README.md +0 -64
- package/.mops/base@0.8.3/mops.toml +0 -6
- package/.mops/base@0.8.3/src/Array.mo +0 -717
- package/.mops/base@0.8.3/src/AssocList.mo +0 -404
- package/.mops/base@0.8.3/src/Blob.mo +0 -212
- package/.mops/base@0.8.3/src/Bool.mo +0 -44
- package/.mops/base@0.8.3/src/Buffer.mo +0 -2660
- package/.mops/base@0.8.3/src/CertifiedData.mo +0 -53
- package/.mops/base@0.8.3/src/Char.mo +0 -65
- package/.mops/base@0.8.3/src/Debug.mo +0 -56
- package/.mops/base@0.8.3/src/Deque.mo +0 -243
- package/.mops/base@0.8.3/src/Error.mo +0 -68
- package/.mops/base@0.8.3/src/ExperimentalCycles.mo +0 -151
- package/.mops/base@0.8.3/src/ExperimentalInternetComputer.mo +0 -60
- package/.mops/base@0.8.3/src/ExperimentalStableMemory.mo +0 -348
- package/.mops/base@0.8.3/src/Float.mo +0 -843
- package/.mops/base@0.8.3/src/Func.mo +0 -46
- package/.mops/base@0.8.3/src/Hash.mo +0 -82
- package/.mops/base@0.8.3/src/HashMap.mo +0 -457
- package/.mops/base@0.8.3/src/Heap.mo +0 -233
- package/.mops/base@0.8.3/src/Int.mo +0 -365
- package/.mops/base@0.8.3/src/Int16.mo +0 -521
- package/.mops/base@0.8.3/src/Int32.mo +0 -522
- package/.mops/base@0.8.3/src/Int64.mo +0 -522
- package/.mops/base@0.8.3/src/Int8.mo +0 -522
- package/.mops/base@0.8.3/src/Iter.mo +0 -227
- package/.mops/base@0.8.3/src/IterType.mo +0 -7
- package/.mops/base@0.8.3/src/List.mo +0 -930
- package/.mops/base@0.8.3/src/Nat.mo +0 -305
- package/.mops/base@0.8.3/src/Nat16.mo +0 -144
- package/.mops/base@0.8.3/src/Nat32.mo +0 -144
- package/.mops/base@0.8.3/src/Nat64.mo +0 -144
- package/.mops/base@0.8.3/src/Nat8.mo +0 -144
- package/.mops/base@0.8.3/src/None.mo +0 -19
- package/.mops/base@0.8.3/src/Option.mo +0 -154
- package/.mops/base@0.8.3/src/Order.mo +0 -46
- package/.mops/base@0.8.3/src/Prelude.mo +0 -33
- package/.mops/base@0.8.3/src/Principal.mo +0 -249
- package/.mops/base@0.8.3/src/RBTree.mo +0 -681
- package/.mops/base@0.8.3/src/Random.mo +0 -270
- package/.mops/base@0.8.3/src/Result.mo +0 -209
- package/.mops/base@0.8.3/src/Stack.mo +0 -93
- package/.mops/base@0.8.3/src/Text.mo +0 -761
- package/.mops/base@0.8.3/src/Time.mo +0 -36
- package/.mops/base@0.8.3/src/Timer.mo +0 -62
- package/.mops/base@0.8.3/src/Trie.mo +0 -1603
- package/.mops/base@0.8.3/src/TrieMap.mo +0 -392
- package/.mops/base@0.8.3/src/TrieSet.mo +0 -148
- package/network.txt +0 -1
|
@@ -1,615 +0,0 @@
|
|
|
1
|
-
/// Text values
|
|
2
|
-
///
|
|
3
|
-
/// This type represents human-readable text as sequences of characters of type `Char`.
|
|
4
|
-
/// If `t` is a value of type `Text`, then:
|
|
5
|
-
///
|
|
6
|
-
/// * `t.chars()` returns an _iterator_ of type `Iter<Char>` enumerating its characters from first to last.
|
|
7
|
-
/// * `t.size()` returns the _size_ (or length) of `t` (and `t.chars()`) as a `Nat`.
|
|
8
|
-
/// * `t1 # t2` concatenates texts `t1` and `t2`.
|
|
9
|
-
///
|
|
10
|
-
/// Represented as ropes of UTF-8 character sequences with O(1) concatenation.
|
|
11
|
-
///
|
|
12
|
-
/// This module defines additional operations on `Text` values.
|
|
13
|
-
|
|
14
|
-
import Char "Char";
|
|
15
|
-
import Iter "Iter";
|
|
16
|
-
import Hash "Hash";
|
|
17
|
-
import Stack "Stack";
|
|
18
|
-
import Prim "mo:⛔";
|
|
19
|
-
|
|
20
|
-
module {
|
|
21
|
-
|
|
22
|
-
/// Text values.
|
|
23
|
-
public type Text = Prim.Types.Text;
|
|
24
|
-
|
|
25
|
-
/// Conversion.
|
|
26
|
-
/// Returns the text value of size 1 containing the single character `c`.
|
|
27
|
-
public let fromChar : (c : Char) -> Text = Prim.charToText;
|
|
28
|
-
|
|
29
|
-
/// Conversion.
|
|
30
|
-
/// Creates an iterator that traverses the characters of the text `t`.
|
|
31
|
-
public func toIter(t : Text) : Iter.Iter<Char> =
|
|
32
|
-
t.chars();
|
|
33
|
-
|
|
34
|
-
/// Conversion.
|
|
35
|
-
/// Returns the text value containing the sequence of characters in `cs`.
|
|
36
|
-
public func fromIter(cs : Iter.Iter<Char>) : Text {
|
|
37
|
-
var r = "";
|
|
38
|
-
for (c in cs) {
|
|
39
|
-
r #= Prim.charToText(c);
|
|
40
|
-
};
|
|
41
|
-
return r;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
/// Returns `t.size()`, the number of characters in `t` (and `t.chars()`).
|
|
45
|
-
public func size(t : Text) : Nat { t.size(); };
|
|
46
|
-
|
|
47
|
-
/// Returns a hash obtained by using the `djb2` algorithm from http://www.cse.yorku.ca/~oz/hash.html
|
|
48
|
-
///
|
|
49
|
-
/// This function is _good enough_ for use in a hash-table but it's not a cryptographic hash function!
|
|
50
|
-
public func hash(t : Text) : Hash.Hash {
|
|
51
|
-
var x : Nat32 = 5381;
|
|
52
|
-
for (char in t.chars()) {
|
|
53
|
-
let c : Nat32 = Prim.charToNat32(char);
|
|
54
|
-
x := ((x << 5) +% x) +% c;
|
|
55
|
-
};
|
|
56
|
-
return x
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
/// Returns the concatenation of `t1` and `t2`, `t1 # t2`.
|
|
60
|
-
public func concat(t1 : Text, t2 : Text) : Text =
|
|
61
|
-
t1 # t2;
|
|
62
|
-
|
|
63
|
-
/// Returns `t1 == t2`.
|
|
64
|
-
public func equal(t1 : Text, t2 : Text) : Bool { t1 == t2 };
|
|
65
|
-
|
|
66
|
-
/// Returns `t1 != t2`.
|
|
67
|
-
public func notEqual(t1 : Text, t2 : Text) : Bool { t1 != t2 };
|
|
68
|
-
|
|
69
|
-
/// Returns `t1 < t2`.
|
|
70
|
-
public func less(t1 : Text, t2 : Text) : Bool { t1 < t2 };
|
|
71
|
-
|
|
72
|
-
/// Returns `t1 <= t2`.
|
|
73
|
-
public func lessOrEqual(t1 : Text, t2 : Text) : Bool { t1 <= t2 };
|
|
74
|
-
|
|
75
|
-
/// Returns `t1 > t2`.
|
|
76
|
-
public func greater(t1 : Text, t2 : Text) : Bool { t1 > t2 };
|
|
77
|
-
|
|
78
|
-
/// Returns `t1 >= t2`.
|
|
79
|
-
public func greaterOrEqual(t1 : Text, t2 : Text) : Bool { t1 >= t2 };
|
|
80
|
-
|
|
81
|
-
/// Returns the order of `t1` and `t2`.
|
|
82
|
-
public func compare(t1 : Text, t2 : Text) : { #less; #equal; #greater } {
|
|
83
|
-
let c = Prim.textCompare(t1, t2);
|
|
84
|
-
if (c < 0) #less else if (c == 0) #equal else #greater
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
private func extract(t : Text, i : Nat, j : Nat) : Text {
|
|
89
|
-
let size = t.size();
|
|
90
|
-
if (i == 0 and j == size) return t;
|
|
91
|
-
assert (j <= size);
|
|
92
|
-
let cs = t.chars();
|
|
93
|
-
var r = "";
|
|
94
|
-
var n = i;
|
|
95
|
-
while (n > 0) {
|
|
96
|
-
ignore cs.next();
|
|
97
|
-
n -= 1;
|
|
98
|
-
};
|
|
99
|
-
n := j;
|
|
100
|
-
while (n > 0) {
|
|
101
|
-
switch (cs.next()) {
|
|
102
|
-
case null { assert false };
|
|
103
|
-
case (?c) { r #= Prim.charToText(c) }
|
|
104
|
-
};
|
|
105
|
-
n -= 1;
|
|
106
|
-
};
|
|
107
|
-
return r;
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
/// Returns the concatenation of text values in `ts`, separated by `sep`.
|
|
111
|
-
public func join(sep : Text, ts : Iter.Iter<Text>) : Text {
|
|
112
|
-
var r = "";
|
|
113
|
-
if (sep.size() == 0) {
|
|
114
|
-
for (t in ts) {
|
|
115
|
-
r #= t
|
|
116
|
-
};
|
|
117
|
-
return r;
|
|
118
|
-
};
|
|
119
|
-
let next = ts.next;
|
|
120
|
-
switch (next()) {
|
|
121
|
-
case null { return r; };
|
|
122
|
-
case (?t) {
|
|
123
|
-
r #= t;
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
loop {
|
|
127
|
-
switch (next()) {
|
|
128
|
-
case null { return r; };
|
|
129
|
-
case (?t) {
|
|
130
|
-
r #= sep;
|
|
131
|
-
r #= t;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
/// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate single-character text values.
|
|
139
|
-
public func map(t : Text, f : Char -> Char) : Text {
|
|
140
|
-
var r = "";
|
|
141
|
-
for (c in t.chars()) {
|
|
142
|
-
r #= Prim.charToText(f(c));
|
|
143
|
-
};
|
|
144
|
-
return r;
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
/// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate text values.
|
|
148
|
-
public func translate(t : Text, f : Char -> Text) : Text {
|
|
149
|
-
var r = "";
|
|
150
|
-
for (c in t.chars()) {
|
|
151
|
-
r #= f(c);
|
|
152
|
-
};
|
|
153
|
-
return r;
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/// A pattern `p` describes a sequence of characters. A pattern has one of the following forms:
|
|
158
|
-
///
|
|
159
|
-
/// * `#char c` matches the single character sequence, `c`.
|
|
160
|
-
/// * `#predicate p` matches any single character sequence `c` satisfying predicate `p(c)`.
|
|
161
|
-
/// * `#text t` matches multi-character text sequence `t`.
|
|
162
|
-
///
|
|
163
|
-
/// A _match_ for `p` is any sequence of characters matching the pattern `p`.
|
|
164
|
-
public type Pattern = { #char : Char; #text : Text; #predicate : (Char -> Bool) };
|
|
165
|
-
|
|
166
|
-
private func take(n : Nat, cs : Iter.Iter<Char>) : Iter.Iter<Char> {
|
|
167
|
-
var i = n;
|
|
168
|
-
object {
|
|
169
|
-
public func next() : ?Char {
|
|
170
|
-
if (i == 0) return null;
|
|
171
|
-
i -= 1;
|
|
172
|
-
return cs.next();
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
private func empty() : Iter.Iter<Char> {
|
|
178
|
-
object {
|
|
179
|
-
public func next() : ?Char = null;
|
|
180
|
-
};
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
private type Match = {
|
|
184
|
-
/// #success on complete match
|
|
185
|
-
#success;
|
|
186
|
-
/// #fail(cs,c) on partial match of cs, but failing match on c
|
|
187
|
-
#fail : (cs : Iter.Iter<Char>, c : Char);
|
|
188
|
-
/// #empty(cs) on partial match of cs and empty stream
|
|
189
|
-
#empty : (cs : Iter.Iter<Char> )
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
private func sizeOfPattern(pat : Pattern) : Nat {
|
|
193
|
-
switch pat {
|
|
194
|
-
case (#text(t)) { t.size() };
|
|
195
|
-
case (#predicate(_) or #char(_)) { 1 };
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
private func matchOfPattern(pat : Pattern) : (cs : Iter.Iter<Char>) -> Match {
|
|
200
|
-
switch pat {
|
|
201
|
-
case (#char(p)) {
|
|
202
|
-
func (cs : Iter.Iter<Char>) : Match {
|
|
203
|
-
switch (cs.next()) {
|
|
204
|
-
case (?c) {
|
|
205
|
-
if (p == c) {
|
|
206
|
-
#success
|
|
207
|
-
} else {
|
|
208
|
-
#fail(empty(), c) }
|
|
209
|
-
};
|
|
210
|
-
case null { #empty(empty()) };
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
case (#predicate(p)) {
|
|
215
|
-
func (cs : Iter.Iter<Char>) : Match {
|
|
216
|
-
switch (cs.next()) {
|
|
217
|
-
case (?c) {
|
|
218
|
-
if (p(c)) {
|
|
219
|
-
#success
|
|
220
|
-
} else {
|
|
221
|
-
#fail(empty(), c) }
|
|
222
|
-
};
|
|
223
|
-
case null { #empty(empty()) };
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
case (#text(p)) {
|
|
228
|
-
func (cs : Iter.Iter<Char>) : Match {
|
|
229
|
-
var i = 0;
|
|
230
|
-
let ds = p.chars();
|
|
231
|
-
loop {
|
|
232
|
-
switch (ds.next()) {
|
|
233
|
-
case (?d) {
|
|
234
|
-
switch (cs.next()) {
|
|
235
|
-
case (?c) {
|
|
236
|
-
if (c != d) {
|
|
237
|
-
return #fail(take(i, p.chars()), c)
|
|
238
|
-
};
|
|
239
|
-
i += 1;
|
|
240
|
-
};
|
|
241
|
-
case null {
|
|
242
|
-
return #empty(take(i, p.chars()));
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
case null { return #success };
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
private class CharBuffer(cs : Iter.Iter<Char>) : Iter.Iter<Char> = {
|
|
255
|
-
|
|
256
|
-
var stack : Stack.Stack<(Iter.Iter<Char>, Char)> = Stack.Stack();
|
|
257
|
-
|
|
258
|
-
public func pushBack(cs0: Iter.Iter<Char>, c : Char) {
|
|
259
|
-
stack.push((cs0, c));
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
public func next() : ?Char {
|
|
263
|
-
switch (stack.peek()) {
|
|
264
|
-
case (?(buff, c)) {
|
|
265
|
-
switch (buff.next()) {
|
|
266
|
-
case null {
|
|
267
|
-
ignore stack.pop();
|
|
268
|
-
return ?c;
|
|
269
|
-
};
|
|
270
|
-
case oc {
|
|
271
|
-
return oc;
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
case null {
|
|
276
|
-
return cs.next();
|
|
277
|
-
};
|
|
278
|
-
};
|
|
279
|
-
};
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
/// Returns the sequence of fields in `t`, derived from start to end,
|
|
283
|
-
/// separated by text matching pattern `p`.
|
|
284
|
-
/// Two fields are separated by exactly one match.
|
|
285
|
-
public func split(t : Text, p : Pattern) : Iter.Iter<Text> {
|
|
286
|
-
let match = matchOfPattern(p);
|
|
287
|
-
let cs = CharBuffer(t.chars());
|
|
288
|
-
var state = 0;
|
|
289
|
-
var field = "";
|
|
290
|
-
object {
|
|
291
|
-
public func next() : ?Text {
|
|
292
|
-
switch state {
|
|
293
|
-
case (0 or 1) {
|
|
294
|
-
loop {
|
|
295
|
-
switch (match(cs)) {
|
|
296
|
-
case (#success) {
|
|
297
|
-
let r = field;
|
|
298
|
-
field := "";
|
|
299
|
-
state := 1;
|
|
300
|
-
return ?r
|
|
301
|
-
};
|
|
302
|
-
case (#empty(cs1)) {
|
|
303
|
-
for (c in cs1) {
|
|
304
|
-
field #= fromChar(c);
|
|
305
|
-
};
|
|
306
|
-
let r =
|
|
307
|
-
if (state == 0 and field == "") {
|
|
308
|
-
null
|
|
309
|
-
} else {
|
|
310
|
-
?field
|
|
311
|
-
};
|
|
312
|
-
state := 2;
|
|
313
|
-
return r;
|
|
314
|
-
};
|
|
315
|
-
case (#fail(cs1, c)) {
|
|
316
|
-
cs.pushBack(cs1,c);
|
|
317
|
-
switch (cs.next()) {
|
|
318
|
-
case (?ci) {
|
|
319
|
-
field #= fromChar(ci);
|
|
320
|
-
};
|
|
321
|
-
case null {
|
|
322
|
-
let r =
|
|
323
|
-
if (state == 0 and field == "") {
|
|
324
|
-
null
|
|
325
|
-
} else {
|
|
326
|
-
?field
|
|
327
|
-
};
|
|
328
|
-
state := 2;
|
|
329
|
-
return r;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
};
|
|
336
|
-
case _ { return null };
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
/// Returns the sequence of tokens in `t`, derived from start to end.
|
|
343
|
-
/// A _token_ is a non-empty maximal subsequence of `t` not containing a match for pattern `p`.
|
|
344
|
-
/// Two tokens may be separated by one or more matches of `p`.
|
|
345
|
-
public func tokens(t : Text, p : Pattern) : Iter.Iter<Text> {
|
|
346
|
-
let fs = split(t, p);
|
|
347
|
-
object {
|
|
348
|
-
public func next() : ?Text {
|
|
349
|
-
switch (fs.next()) {
|
|
350
|
-
case (?"") { next() };
|
|
351
|
-
case ot { ot };
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
|
|
357
|
-
/// Returns true if `t` contains a match for pattern `p`.
|
|
358
|
-
public func contains(t : Text, p : Pattern) : Bool {
|
|
359
|
-
let match = matchOfPattern(p);
|
|
360
|
-
let cs = CharBuffer(t.chars());
|
|
361
|
-
loop {
|
|
362
|
-
switch (match(cs)) {
|
|
363
|
-
case (#success) {
|
|
364
|
-
return true
|
|
365
|
-
};
|
|
366
|
-
case (#empty(cs1)) {
|
|
367
|
-
return false;
|
|
368
|
-
};
|
|
369
|
-
case (#fail(cs1, c)) {
|
|
370
|
-
cs.pushBack(cs1, c);
|
|
371
|
-
switch (cs.next()) {
|
|
372
|
-
case null {
|
|
373
|
-
return false
|
|
374
|
-
};
|
|
375
|
-
case _ { }; // continue
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
/// Returns `true` if `t` starts with a prefix matching pattern `p`, otherwise returns `false`.
|
|
383
|
-
public func startsWith(t : Text, p : Pattern) : Bool {
|
|
384
|
-
var cs = t.chars();
|
|
385
|
-
let match = matchOfPattern(p);
|
|
386
|
-
switch (match(cs)) {
|
|
387
|
-
case (#success) { true };
|
|
388
|
-
case _ { false };
|
|
389
|
-
}
|
|
390
|
-
};
|
|
391
|
-
|
|
392
|
-
/// Returns `true` if `t` ends with a suffix matching pattern `p`, otherwise returns `false`.
|
|
393
|
-
public func endsWith(t : Text, p : Pattern) : Bool {
|
|
394
|
-
let s2 = sizeOfPattern(p);
|
|
395
|
-
if (s2 == 0) return true;
|
|
396
|
-
let s1 = t.size();
|
|
397
|
-
if (s2 > s1) return false;
|
|
398
|
-
let match = matchOfPattern(p);
|
|
399
|
-
var cs1 = t.chars();
|
|
400
|
-
var diff : Nat = s1 - s2;
|
|
401
|
-
while (diff > 0) {
|
|
402
|
-
ignore cs1.next();
|
|
403
|
-
diff -= 1;
|
|
404
|
-
};
|
|
405
|
-
switch (match(cs1)) {
|
|
406
|
-
case (#success) { true };
|
|
407
|
-
case _ { false };
|
|
408
|
-
}
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
/// Returns `t` with all matches of pattern `p` replaced by text `r`.
|
|
412
|
-
public func replace(t : Text, p : Pattern, r : Text) : Text {
|
|
413
|
-
let match = matchOfPattern(p);
|
|
414
|
-
let size = sizeOfPattern(p);
|
|
415
|
-
let cs = CharBuffer(t.chars());
|
|
416
|
-
var res = "";
|
|
417
|
-
label l
|
|
418
|
-
loop {
|
|
419
|
-
switch (match(cs)) {
|
|
420
|
-
case (#success) {
|
|
421
|
-
res #= r;
|
|
422
|
-
if (size > 0) {
|
|
423
|
-
continue l;
|
|
424
|
-
}
|
|
425
|
-
};
|
|
426
|
-
case (#empty(cs1)) {
|
|
427
|
-
for (c1 in cs1) {
|
|
428
|
-
res #= fromChar(c1);
|
|
429
|
-
};
|
|
430
|
-
break l;
|
|
431
|
-
};
|
|
432
|
-
case (#fail(cs1, c)) {
|
|
433
|
-
cs.pushBack(cs1, c);
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
switch (cs.next()) {
|
|
437
|
-
case null {
|
|
438
|
-
break l;
|
|
439
|
-
};
|
|
440
|
-
case (?c1) {
|
|
441
|
-
res #= fromChar(c1);
|
|
442
|
-
}; // continue
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
return res;
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
/// Returns the optioned suffix of `t` obtained by eliding exactly one leading match of pattern `p`, otherwise `null`.
|
|
451
|
-
public func stripStart(t : Text, p : Pattern) : ?Text {
|
|
452
|
-
let s = sizeOfPattern(p);
|
|
453
|
-
if (s == 0) return ?t;
|
|
454
|
-
var cs = t.chars();
|
|
455
|
-
let match = matchOfPattern(p);
|
|
456
|
-
switch (match(cs)) {
|
|
457
|
-
case (#success) return ?fromIter(cs);
|
|
458
|
-
case _ return null;
|
|
459
|
-
}
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
/// Returns the optioned prefix of `t` obtained by eliding exactly one trailing match of pattern `p`, otherwise `null`.
|
|
463
|
-
public func stripEnd(t : Text, p : Pattern) : ?Text {
|
|
464
|
-
let s2 = sizeOfPattern(p);
|
|
465
|
-
if (s2 == 0) return ?t;
|
|
466
|
-
let s1 = t.size();
|
|
467
|
-
if (s2 > s1) return null;
|
|
468
|
-
let match = matchOfPattern(p);
|
|
469
|
-
var cs1 = t.chars();
|
|
470
|
-
var diff : Nat = s1 - s2;
|
|
471
|
-
while (diff > 0) {
|
|
472
|
-
ignore cs1.next();
|
|
473
|
-
diff -= 1;
|
|
474
|
-
};
|
|
475
|
-
switch (match(cs1)) {
|
|
476
|
-
case (#success) return ?extract(t, 0, s1 - s2);
|
|
477
|
-
case _ return null;
|
|
478
|
-
}
|
|
479
|
-
};
|
|
480
|
-
|
|
481
|
-
/// Returns the suffix of `t` obtained by eliding all leading matches of pattern `p`.
|
|
482
|
-
public func trimStart(t : Text, p : Pattern) : Text {
|
|
483
|
-
let cs = t.chars();
|
|
484
|
-
let size = sizeOfPattern(p);
|
|
485
|
-
if (size == 0) return t;
|
|
486
|
-
var matchSize = 0;
|
|
487
|
-
let match = matchOfPattern(p);
|
|
488
|
-
loop {
|
|
489
|
-
switch (match(cs)) {
|
|
490
|
-
case (#success) {
|
|
491
|
-
matchSize += size;
|
|
492
|
-
}; // continue
|
|
493
|
-
case (#empty(cs1)) {
|
|
494
|
-
return if (matchSize == 0) {
|
|
495
|
-
t
|
|
496
|
-
} else {
|
|
497
|
-
fromIter(cs1)
|
|
498
|
-
}
|
|
499
|
-
};
|
|
500
|
-
case (#fail(cs1, c)) {
|
|
501
|
-
return if (matchSize == 0) {
|
|
502
|
-
t
|
|
503
|
-
} else {
|
|
504
|
-
fromIter(cs1) # fromChar(c) # fromIter(cs)
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
};
|
|
510
|
-
|
|
511
|
-
/// Returns the prefix of `t` obtained by eliding all trailing matches of pattern `p`.
|
|
512
|
-
public func trimEnd(t : Text, p : Pattern) : Text {
|
|
513
|
-
let cs = CharBuffer(t.chars());
|
|
514
|
-
let size = sizeOfPattern(p);
|
|
515
|
-
if (size == 0) return t;
|
|
516
|
-
let match = matchOfPattern(p);
|
|
517
|
-
var matchSize = 0;
|
|
518
|
-
label l
|
|
519
|
-
loop {
|
|
520
|
-
switch (match(cs)) {
|
|
521
|
-
case (#success) {
|
|
522
|
-
matchSize += size;
|
|
523
|
-
}; // continue
|
|
524
|
-
case (#empty(cs1)) {
|
|
525
|
-
switch (cs1.next()) {
|
|
526
|
-
case null break l;
|
|
527
|
-
case (?_) return t;
|
|
528
|
-
}
|
|
529
|
-
};
|
|
530
|
-
case (#fail(cs1, c)) {
|
|
531
|
-
matchSize := 0;
|
|
532
|
-
cs.pushBack(cs1, c);
|
|
533
|
-
ignore cs.next();
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
};
|
|
537
|
-
extract(t, 0, t.size() - matchSize)
|
|
538
|
-
};
|
|
539
|
-
|
|
540
|
-
/// Returns the subtext of `t` obtained by eliding all leading and trailing matches of pattern `p`.
|
|
541
|
-
public func trim(t : Text, p : Pattern) : Text {
|
|
542
|
-
let cs = t.chars();
|
|
543
|
-
let size = sizeOfPattern(p);
|
|
544
|
-
if (size == 0) return t;
|
|
545
|
-
var matchSize = 0;
|
|
546
|
-
let match = matchOfPattern(p);
|
|
547
|
-
loop {
|
|
548
|
-
switch (match(cs)) {
|
|
549
|
-
case (#success) {
|
|
550
|
-
matchSize += size;
|
|
551
|
-
}; // continue
|
|
552
|
-
case (#empty(cs1)) {
|
|
553
|
-
return if (matchSize == 0) { t } else { fromIter(cs1) }
|
|
554
|
-
};
|
|
555
|
-
case (#fail(cs1, c)) {
|
|
556
|
-
let start = matchSize;
|
|
557
|
-
let cs2 = CharBuffer(cs);
|
|
558
|
-
cs2.pushBack(cs1, c);
|
|
559
|
-
ignore cs2.next();
|
|
560
|
-
matchSize := 0;
|
|
561
|
-
label l
|
|
562
|
-
loop {
|
|
563
|
-
switch (match(cs2)) {
|
|
564
|
-
case (#success) {
|
|
565
|
-
matchSize += size;
|
|
566
|
-
}; // continue
|
|
567
|
-
case (#empty(cs3)) {
|
|
568
|
-
switch (cs1.next()) {
|
|
569
|
-
case null break l;
|
|
570
|
-
case (?_) return t;
|
|
571
|
-
}
|
|
572
|
-
};
|
|
573
|
-
case (#fail(cs3, c1)) {
|
|
574
|
-
matchSize := 0;
|
|
575
|
-
cs2.pushBack(cs3, c1);
|
|
576
|
-
ignore cs2.next();
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
};
|
|
580
|
-
return extract(t, start, t.size() - matchSize - start);
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
};
|
|
585
|
-
|
|
586
|
-
/// Returns the lexicographic comparison of `t1` and `t2`, using the given character ordering `cmp`.
|
|
587
|
-
public func compareWith(
|
|
588
|
-
t1 : Text,
|
|
589
|
-
t2 : Text,
|
|
590
|
-
cmp : (Char, Char)-> { #less; #equal; #greater })
|
|
591
|
-
: { #less; #equal; #greater } {
|
|
592
|
-
let cs1 = t1.chars();
|
|
593
|
-
let cs2 = t2.chars();
|
|
594
|
-
loop {
|
|
595
|
-
switch (cs1.next(), cs2.next()) {
|
|
596
|
-
case (null, null) { return #equal };
|
|
597
|
-
case (null, ?_) { return #less };
|
|
598
|
-
case (?_, null) { return #greater };
|
|
599
|
-
case (?c1, ?c2) {
|
|
600
|
-
switch (cmp(c1, c2)) {
|
|
601
|
-
case (#equal) { }; // continue
|
|
602
|
-
case other { return other; }
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
};
|
|
608
|
-
|
|
609
|
-
/// Returns the UTF-8 encoding of the given text
|
|
610
|
-
public let encodeUtf8 : Text -> Blob = Prim.encodeUtf8;
|
|
611
|
-
|
|
612
|
-
/// Tries to decode the given `Blob` as UTF-8.
|
|
613
|
-
/// Returns `null` if the blob is _not_ valid UTF-8.
|
|
614
|
-
public let decodeUtf8 : Blob -> ?Text = Prim.decodeUtf8;
|
|
615
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/// System time
|
|
2
|
-
|
|
3
|
-
import Prim "mo:⛔";
|
|
4
|
-
module {
|
|
5
|
-
|
|
6
|
-
/// System time is represent as nanoseconds since 1970-01-01.
|
|
7
|
-
public type Time = Int;
|
|
8
|
-
|
|
9
|
-
/// Current system time given as nanoseconds since 1970-01-01. The system guarantees that:
|
|
10
|
-
///
|
|
11
|
-
/// * the time, as observed by the canister smart contract, is monotonically increasing, even across canister upgrades.
|
|
12
|
-
/// * within an invocation of one entry point, the time is constant.
|
|
13
|
-
///
|
|
14
|
-
/// The system times of different canisters are unrelated, and calls from one canister to another may appear to travel "backwards in time"
|
|
15
|
-
///
|
|
16
|
-
/// Note: While an implementation will likely try to keep the system time close to the real time, this is not formally guaranteed.
|
|
17
|
-
public let now : () -> Time =
|
|
18
|
-
func () : Int = Prim.nat64ToNat(Prim.time());
|
|
19
|
-
///
|
|
20
|
-
/// The following example illustrates using the system time:
|
|
21
|
-
///
|
|
22
|
-
/// ```motoko
|
|
23
|
-
/// import Int = "mo:base/Int";
|
|
24
|
-
/// import Time = "mo:base/Time";
|
|
25
|
-
///
|
|
26
|
-
/// actor {
|
|
27
|
-
/// var lastTime = Time.now();
|
|
28
|
-
/// public func greet(name : Text) : async Text {
|
|
29
|
-
/// let now = Time.now();
|
|
30
|
-
/// let elapsedSeconds = (now - lastTime) / 1000_000_000;
|
|
31
|
-
/// lastTime := now;
|
|
32
|
-
/// return "Hello, " # name # "!" #
|
|
33
|
-
/// " I was last called " # Int.toText(elapsedSeconds) # " seconds ago";
|
|
34
|
-
/// };
|
|
35
|
-
/// };
|
|
36
|
-
/// ```
|
|
37
|
-
}
|