• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

moonbitlang / x / 228

23 Sep 2024 10:19AM UTC coverage: 88.497% (-5.9%) from 94.361%
228

push

github

web-flow
add multi backend support for fs io (#59)

* wasm

* js

* basiclly done

* add comment

* moon info

* use Bytes instead of Array[Byte]

* use guard and type!

* moon fmt

* enable coverage-check-bleeding

* bump version

* polish error show msg

40 of 47 new or added lines in 5 files covered. (85.11%)

96 existing lines in 20 files now uncovered.

1054 of 1191 relevant lines covered (88.5%)

471.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.72
/stack/stack.mbt
1
// Copyright 2024 International Digital Economy Academy
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
/// Create an empty stack.
16
///
17
/// # Example
18
///
19
/// ```
20
/// let s : Stack[Int] = Stack::new()
21
/// println(s) // Stack::[]
22
/// ```
23
pub fn Stack::new[T]() -> Stack[T] {
24
  { elements: Nil, len: 0 }
10✔
25
}
26

27
test "new" {
28
  let s : Stack[Int] = Stack::new()
29
  inspect!(s, content="Stack::[]")
30
}
31

32
/// Create a stack based on all elements in list.
33
///
34
/// # Example
35
///
36
/// ```
37
/// let s = Stack::from_list(@immut/list.of([1, 2, 3]))
38
/// println(s) // Stack::[1, 2, 3]
39
/// ```
40
pub fn Stack::from_list[T](list : @immut/list.T[T]) -> Stack[T] {
41
  { elements: list, len: list.length() }
1✔
42
}
43

44
test "from_list" {
45
  let s = Stack::from_list(@immut/list.of([1, 2, 3]))
46
  inspect!(s, content="Stack::[1, 2, 3]")
47
  inspect!(s.len, content="3")
48
}
49

50
/// Create a stack based on all elements in array.
51
///
52
/// # Example
53
///
54
/// ```
55
/// let s = Stack::from_array([1, 2, 3])
56
/// println(s) // Stack::from_array([3, 2, 1])
57
/// ```
58
pub fn Stack::from_array[T](array : Array[T]) -> Stack[T] {
59
  { elements: @immut/list.from_array(array), len: array.length() }
1✔
60
}
61

62
test "from_array" {
63
  let s = Stack::from_array([1, 2, 3])
64
  inspect!(s, content="Stack::[1, 2, 3]")
65
  inspect!(s.len, content="3")
66
}
67

68
/// Create a stack based on all elements in array.
69
///
70
/// # Example
71
///
72
/// ```
73
/// let s = Stack::of([1, 2, 3])
74
/// println(s) // Stack::of([3, 2, 1])
75
/// ```
76
pub fn Stack::of[T](array : FixedArray[T]) -> Stack[T] {
77
  { elements: @immut/list.of(array), len: array.length() }
20✔
78
}
79

80
test "of" {
81
  let s = Stack::of([1, 2, 3])
82
  inspect!(s, content="Stack::[1, 2, 3]")
83
  inspect!(s.len, content="3")
84
}
85

86
pub fn to_string[T : Show](self : Stack[T]) -> String {
87
  let mut res = "Stack::["
19✔
88
  self.elements.eachi(
89
    fn(i, t) {
90
      if i > 0 {
38✔
91
        res += ", "
24✔
92
      }
93
      res += t.to_string()
94
    },
95
  )
96
  res + "]"
97
}
98

99
pub fn output[T : Show](self : Stack[T], logger : Logger) -> Unit {
100
  logger.write_string(self.to_string())
19✔
101
}
102

103
test "to_string" {
104
  let empty : Stack[Int] = new()
105
  inspect!(empty, content="Stack::[]")
106
  inspect!(Stack::of([1, 2, 3, 4, 5]), content="Stack::[1, 2, 3, 4, 5]")
107
}
108

109
/// Create a stack based on another stack.
110
///
111
/// # Example
112
///
113
/// ```
114
/// let s = Stack::of([1, 2, 3])
115
/// let s1 = Stack::from_stack(s)
116
/// println(s1) // output: Stack::[3, 2, 1]
117
/// ```
118
pub fn Stack::from_stack[T](other : Stack[T]) -> Stack[T] {
119
  { ..other }
1✔
120
}
121

122
test "from_stack" {
123
  let s = Stack::of([1, 2, 3])
124
  let s1 = Stack::from_stack(s)
125
  inspect!(s1.elements == s.elements, content="true")
126
}
127

128
/// Clear all elements in Stack
129
/// 
130
/// # Example
131
///
132
/// ```
133
/// let s = Stack::of([1, 2, 3])
134
/// s.clear()
135
/// println(s) // Stack::[]
136
/// ```
137
pub fn clear[T](self : Stack[T]) -> Unit {
138
  self.elements = Nil
2✔
139
  self.len = 0
140
}
141

142
test "clear" {
143
  let s = Stack::of([1, 2, 3])
144
  s.clear()
145
  inspect!(s, content="Stack::[]")
146
}
147

148
/// Same as the `clear()`, but returns an cleared stack
149
///
150
/// # Example
151
///
152
/// ```
153
/// let s = Stack::of([1, 2, 3]).return_with_clear()
154
/// println(s) // Stack::[]
155
/// ```
156
pub fn return_with_clear[T](self : Stack[T]) -> Stack[T] {
157
  self.clear()
1✔
158
  self
159
}
160

161
test "return_with_clear" {
162
  let s = Stack::of([1, 2, 3]).return_with_clear()
163
  inspect!(s, content="Stack::[]")
164
}
165

166
/// Push an element into the stack.
167
/// 
168
/// # Example
169
///
170
/// ```
171
/// let s = Stack::new()
172
/// s.push(1)
173
/// println(s) // Stack::[1]
174
/// ```
175
pub fn push[T](self : Stack[T], x : T) -> Unit {
176
  self.elements = Cons(x, self.elements)
13✔
177
  self.len = self.len + 1
178
}
179

180
test "push" {
181
  let s = Stack::new()
182
  s.push(1)
183
  inspect!(s, content="Stack::[1]")
184
  inspect!(s.len, content="1")
185
}
186

187
/// Push a list into the stack.
188
/// 
189
/// # Example
190
///
191
/// ```
192
/// let s = Stack::new()
193
/// s.push_list(@immut/list.of[1, 2, 3])
194
/// println(s) // Stack::[3, 2, 1]
195
/// ```
196
pub fn push_list[T](self : Stack[T], list : @immut/list.T[T]) -> Unit {
197
  list.each(fn(i) { self.push(i) })
1✔
198
}
199

200
test "push_list" {
201
  let s = Stack::new()
202
  s.push_list(@immut/list.of([1, 2, 3]))
203
  inspect!(s, content="Stack::[3, 2, 1]")
204
  inspect!(s.len, content="3")
205
}
206

207
/// Push other stack into the current stack.
208
/// 
209
/// # Example
210
///
211
/// ```
212
/// let s = Stack::of([1, 2, 3])
213
/// let s1 : Stack[Int] = Stack::new()
214
/// s1.push_stack(s)
215
/// println(s1) // Stack::[1, 2, 3]
216
/// ```
217
pub fn push_stack[T](self : Stack[T], stack : Stack[T]) -> Unit {
218
  stack.elements.each(fn(i) { self.push(i) })
1✔
219
}
220

221
test "push_stack" {
222
  let s = Stack::of([1, 2, 3])
223
  let s1 : Stack[Int] = Stack::new()
224
  s1.push_stack(s)
225
  inspect!(s1, content="Stack::[3, 2, 1]")
226
  inspect!(s.len == s1.len, content="true")
227
}
228

229
/// Push an array into the stack.
230
/// 
231
/// # Example
232
///
233
/// ```
234
/// let s : Stack[Int] = Stack::new()
235
/// s.push_array([1, 2, 3])
236
/// println(s) // Stack::[3, 2, 1]
237
/// ```
238
pub fn push_array[T](self : Stack[T], array : Array[T]) -> Unit {
239
  array.each(fn(i) { self.push(i) })
1✔
240
}
241

242
test "push_array" {
243
  let s : Stack[Int] = Stack::new()
244
  s.push_array([1, 2, 3])
245
  inspect!(s, content="Stack::[3, 2, 1]")
246
  inspect!(s.len, content="3")
247
}
248

249
/// Pop an element from the top of the stack.
250
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
251
///
252
/// # Example
253
///
254
/// ```
255
/// let s = Stack::of([1, 2, 3])
256
/// let s1 : Stack[Int] = Stack::new()
257
/// println(s.pop()) // Some(1)
258
/// println(s) // Stack::[2, 3]
259
/// println(s1.pop()) // None
260
/// ```
261
pub fn pop[T](self : Stack[T]) -> T? {
262
  match self.elements {
2✔
263
    Cons(hd, tl) => {
1✔
264
      self.elements = tl
265
      self.len = self.len - 1
266
      Some(hd)
267
    }
268
    Nil => None
1✔
269
  }
270
}
271

272
test "pop" {
273
  let s = Stack::of([1, 2, 3])
274
  let s1 : Stack[Int] = Stack::new()
275
  inspect!(s.pop(), content="Some(1)")
276
  inspect!(s, content="Stack::[2, 3]")
277
  inspect!(s.len, content="2")
278
  inspect!(s1.pop(), content="None")
279
  inspect!(s1, content="Stack::[]")
280
  inspect!(s1.len, content="0")
281
}
282

283
/// Pop an element from the top of the stack.
284
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
285
///
286
/// # Example
287
///
288
/// ```
289
/// let s = Stack::of([1, 2, 3])
290
/// let s1 : Stack[Int] = Stack::new()
291
/// println(s.unsafe_pop()) // 1
292
/// println(s) // Stack::[2, 3]
293
/// println(s1.unsafe_pop()) // abort.
294
/// ```
295
/// @alert unsafe "Panic if the stack is empty."
296
pub fn unsafe_pop[T](self : Stack[T]) -> T {
297
  match self.elements {
1✔
298
    Cons(hd, tl) => {
1✔
299
      self.elements = tl
300
      self.len = self.len - 1
301
      hd
302
    }
UNCOV
303
    Nil => abort("pop of empty stack")
×
304
  }
305
}
306

307
test "unsafe_pop" {
308
  let s = Stack::of([1, 2, 3])
309
  inspect!(s.unsafe_pop(), content="1")
310
  inspect!(s, content="Stack::[2, 3]")
311
  inspect!(s.len, content="2")
312
}
313

314
/// Drop the element at the top of the stack.
315
/// Like pop, but does not return elements and does nothing if the Stack is empty.
316
///
317
/// # Example
318
///
319
/// ```
320
/// let s = Stack::of([1, 2, 3])
321
/// s.drop()
322
/// println(s) // Stack::[2, 3]
323
/// ```
324
pub fn drop[T](self : Stack[T]) -> Unit {
325
  match self.elements {
1✔
326
    Cons(_hd, tl) => {
1✔
327
      self.elements = tl
328
      self.len = self.len - 1
329
    }
UNCOV
330
    Nil => ()
×
331
  }
332
}
333

334
test "drop" {
335
  let s = Stack::of([1, 2, 3])
336
  s.drop()
337
  inspect!(s, content="Stack::[2, 3]")
338
  inspect!(s.len, content="2")
339
}
340

341
/// Drop the element at the top of the stack.
342
/// Like drop, but when the drop is successful, it returns `Ok(())`, and when it fails, it returns `Err(())`
343
///
344
/// # Example
345
///
346
/// ```
347
/// let s = Stack::of([1, 2, 3])
348
/// let r = s.drop_result() // Ok(())
349
/// ```
350
pub fn drop_result[T](self : Stack[T]) -> Result[Unit, Unit] {
351
  match self.elements {
2✔
352
    Cons(_hd, tl) => {
1✔
353
      self.elements = tl
354
      self.len = self.len - 1
355
      Ok(())
356
    }
357
    Nil => Err(())
1✔
358
  }
359
}
360

361
test "drop_result" {
362
  let s = Stack::of([1, 2, 3])
363
  let s1 : Stack[Int] = Stack::new()
364
  inspect!(s1.drop_result() == Err(()), content="true")
365
  inspect!(s.drop_result() == Ok(()), content="true")
366
  inspect!(s, content="Stack::[2, 3]")
367
  inspect!(s.len, content="2")
368
}
369

370
/// Only the top element of the stack is returned and will not be pop or drop.
371
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
372
///
373
/// # Example
374
///
375
/// ```
376
/// let s = Stack::from_array([1, 2, 3])
377
/// println(s.peek()) // Some(1)
378
/// println(s) // Stack::[1, 2, 3]
379
/// ```
380
pub fn peek[T](self : Stack[T]) -> T? {
381
  match self.elements {
1✔
382
    Cons(hd, _) => Some(hd)
1✔
UNCOV
383
    Nil => None
×
384
  }
385
}
386

387
test "peek" {
388
  let s = Stack::of([1, 2, 3])
389
  inspect!(s.peek(), content="Some(1)")
390
  inspect!(s, content="Stack::[1, 2, 3]")
391
  inspect!(s.len, content="3")
392
}
393

394
/// Only the top element of the stack is returned and will not be pop or drop.
395
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
396
///
397
/// # Example
398
///
399
/// ```
400
/// let s = Stack::from_array([1, 2, 3])
401
/// let s1 : Stack[Int] = Stack::new()
402
/// println(s1.peek_exn()) // abort
403
/// println(s.peek_exn()) // 1
404
/// println(s) // Stack::[1, 2, 3]
405
/// ```
406
/// @alert unsafe "Panic if the stack is empty."
407
pub fn peek_exn[T](self : Stack[T]) -> T {
408
  match self.elements {
3✔
409
    Cons(hd, _) => hd
3✔
UNCOV
410
    Nil => abort("top of the empty stack")
×
411
  }
412
}
413

414
test "peek_exn" {
415
  let s : Stack[Int] = Stack::of([1, 2, 3])
416
  inspect!(s.peek_exn(), content="1")
417
  inspect!(s, content="Stack::[1, 2, 3]")
418
  inspect!(s.len, content="3")
419
}
420

421
/// If stack is empty, return true, otherwise return false.
422
///
423
/// # Example
424
///
425
/// ```
426
/// println(Stack::of([1, 2, 3]).is_empty()) // false
427
/// println(Stack::new().is_empty()) // true
428
/// ```
429
pub fn is_empty[T](self : Stack[T]) -> Bool {
430
  self.len == 0
2✔
431
}
432

433
test "is_empty" {
434
  let empty : Stack[Unit] = Stack::new()
435
  inspect!(Stack::of([1, 2, 3]).is_empty(), content="false")
436
  inspect!(empty.is_empty(), content="true")
437
}
438

439
/// Returns the number of elements of the Stack
440
pub fn length[T](self : Stack[T]) -> Int {
UNCOV
441
  self.len
×
442
}
443

444
/// Iterates over the elements of the stack from top to bottom.
445
/// 
446
/// # Example
447
/// ```
448
/// let s = Stack::of([1, 2, 3])
449
/// s.each(fn(i) { println(i) })'
450
/// ```
451
pub fn each[T](self : Stack[T], f : (T) -> Unit) -> Unit {
452
  self.elements.each(f)
3✔
453
}
454

455
test "iter" {
456
  let s : Stack[Int] = new()
457
  let mut sum = 0
458
  let mut sub = 0
459
  s.each(fn(i) { sum = sum + i })
460
  inspect!(sum, content="0")
461
  s.push(1)
462
  s.push(2)
463
  s.push(3)
464
  inspect!(s.peek_exn(), content="3")
465
  sum = 0
466
  sub = s.peek_exn()
467
  s.each(fn(i) { sum = sum + i })
468
  s.each(fn(i) { sub = sub - i }) // 3 - 3 - 2 - 1
469
  inspect!(sum, content="6")
470
  inspect!(sub, content="-3")
471
}
472

473
/// Folds over the elements of the stack from top to bottom.
474
/// 
475
/// # Example
476
/// ```
477
/// let s = Stack::of([1, 2, 3])
478
/// let sum = s.fold(~init=0, fn(acc, i) { acc + i })
479
/// println(sum) // 6
480
/// ```
481
pub fn fold[T, U](self : Stack[T], ~init : U, f : (U, T) -> U) -> U {
482
  self.elements.fold(~init, f)
1✔
483
}
484

485
test "fold" {
486
  let s = Stack::of([1, 2, 3])
487
  let sum = s.fold(init=0, fn(acc, i) { acc + i })
488
  inspect!(sum, content="6")
489
}
490

491
/// Convert stack to list.
492
///
493
/// # Example
494
///
495
/// ```
496
/// println(Stack::of([1, 2, 3]).to_list()) // @immut/list.of([1, 2, 3])
497
/// ```
498
pub fn to_list[T](self : Stack[T]) -> @immut/list.T[T] {
499
  self.elements
1✔
500
}
501

502
test "to_list" {
503
  inspect!(Stack::of([3, 2, 1]).to_list(), content="@list.of([3, 2, 1])")
504
}
505

506
/// Convert stack to array.
507
///
508
/// # Example
509
///
510
/// ```
511
/// println(Stack::of([1, 2, 3]).to_array()) // [1, 2, 3]
512
/// ```
513
pub fn to_array[T : Default](self : Stack[T]) -> Array[T] {
514
  self.elements.to_array()
1✔
515
}
516

517
test "to_array" {
518
  inspect!(Stack::of([3, 2, 1]).to_array(), content="[3, 2, 1]")
519
}
520

521
/// Compare two stacks.
522
///
523
/// NOTE: Since the current standard library @immut/list.T lacks the equal or op_equal function, 
524
/// this function internally implements the equal function of @immut/list.T.
525
///
526
/// # Example
527
///
528
/// ```
529
/// println(Stack::of([2, 4, 6]).equal(Stack::of([2, 4, 6]))) // true
530
/// ```
531
pub fn equal[T : Eq](self : Stack[T], other : Stack[T]) -> Bool {
532
  if self.len == other.len {
2✔
533
    self.elements.equal(other.elements)
2✔
534
  } else {
UNCOV
535
    false
×
536
  }
537
}
538

539
pub fn op_equal[T : Eq](self : Stack[T], other : Stack[T]) -> Bool {
UNCOV
540
  self.equal(other)
×
541
}
542

543
test "equal" {
544
  inspect!(Stack::of([2, 4, 6]).equal(Stack::of([2, 4, 6])), content="true")
545
  inspect!(Stack::of([2, 4, 6]).equal(Stack::of([2, 4, 7])), content="false")
546
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc