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

moonbitlang / x / 534

21 Jul 2025 07:25AM UTC coverage: 89.676% (-0.2%) from 89.897%
534

push

github

peter-jerry-ye
ci: it's 2025 now

1911 of 2131 relevant lines covered (89.68%)

383.81 hits per line

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

86.67
/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
///   assert_true(s.is_empty())
22
/// ```
23
pub fn[T] new() -> Stack[T] {
24
  { elements: Nil, len: 0 }
17✔
25
}
26

27
///|
28
#deprecated("use `@stack.new()` instead")
29
pub fn[T] Stack::new() -> Stack[T] {
30
  { elements: Nil, len: 0 }
31
}
32

33
///|
34
test "new" {
35
  let s : Stack[Int] = new()
36
  inspect(s, content="Stack::[]")
37
}
38

39
///| Create a stack based on all elements in list.
40
///
41
/// # Example
42
///
43
/// ```
44
///   let s = Stack::from_list(@immut/list.of([1, 2, 3]))
45
///   assert_eq(s.length(), 3)
46
/// ```
47
pub fn[T] Stack::from_list(list : @immut/list.T[T]) -> Stack[T] {
48
  { elements: list, len: list.length() }
2✔
49
}
50

51
///|
52
test "from_list" {
53
  let s = Stack::from_list(@immut/list.of([1, 2, 3]))
54
  inspect(s, content="Stack::[1, 2, 3]")
55
  inspect(s.len, content="3")
56
}
57

58
///| Create a stack based on all elements in array.
59
///
60
/// # Example
61
///
62
/// ```
63
///   let s = Stack::from_array([1, 2, 3])
64
///   assert_eq(s.length(), 3)
65
/// ```
66
pub fn[T] Stack::from_array(array : Array[T]) -> Stack[T] {
67
  { elements: @immut/list.from_array(array), len: array.length() }
3✔
68
}
69

70
///|
71
test "from_array" {
72
  let s = Stack::from_array([1, 2, 3])
73
  inspect(s, content="Stack::[1, 2, 3]")
74
  inspect(s.len, content="3")
75
}
76

77
///| Create a stack based on all elements in array.
78
///
79
/// # Example
80
///
81
/// ```
82
///   let s = @stack.of([1, 2, 3])
83
///   assert_eq(s.length(), 3)
84
/// ```
85
#deprecated("use `@stack.of()` instead")
86
pub fn[T] Stack::of(array : FixedArray[T]) -> Stack[T] {
87
  { elements: @immut/list.of(array), len: array.length() }
88
}
89

90
///|
91
pub fn[T] of(array : FixedArray[T]) -> Stack[T] {
92
  { elements: @immut/list.of(array), len: array.length() }
35✔
93
}
94

95
///|
96
test "of" {
97
  let s = of([1, 2, 3])
98
  inspect(s, content="Stack::[1, 2, 3]")
99
  inspect(s.len, content="3")
100
}
101

102
///|
103
pub fn[T : Show] to_string(self : Stack[T]) -> String {
104
  let mut res = "Stack::["
19✔
105
  self.elements.eachi(fn(i, t) {
19✔
106
    if i > 0 {
38✔
107
      res += ", "
24✔
108
    }
109
    res += t.to_string()
38✔
110
  })
111
  res + "]"
112
}
113

114
///|
115
pub impl[T : Show] Show for Stack[T] with output(self, logger : &Logger) -> Unit {
116
  logger.write_string(self.to_string())
19✔
117
}
118

119
///|
120
test "to_string" {
121
  let empty : Stack[Int] = new()
122
  inspect(empty, content="Stack::[]")
123
  inspect(of([1, 2, 3, 4, 5]), content="Stack::[1, 2, 3, 4, 5]")
124
}
125

126
///| Create a stack based on another stack.
127
///
128
/// # Example
129
///
130
/// ```
131
///   let s = @stack.of([1, 2, 3])
132
///   let s1 = Stack::from_stack(s)
133
///   assert_eq(s1.length(), 3)
134
/// ```
135
pub fn[T] Stack::from_stack(other : Stack[T]) -> Stack[T] {
136
  { ..other }
2✔
137
}
138

139
///|
140
test "from_stack" {
141
  let s = of([1, 2, 3])
142
  let s1 = Stack::from_stack(s)
143
  inspect(s1.elements == s.elements, content="true")
144
}
145

146
///| Clear all elements in Stack
147
/// 
148
/// # Example
149
///
150
/// ```
151
///   let s = @stack.of([1, 2, 3])
152
///   s.clear()
153
///   assert_eq(s.length(), 0)
154
/// ```
155
pub fn[T] clear(self : Stack[T]) -> Unit {
156
  self.elements = Nil
4✔
157
  self.len = 0
158
}
159

160
///|
161
test "clear" {
162
  let s = of([1, 2, 3])
163
  s.clear()
164
  inspect(s, content="Stack::[]")
165
}
166

167
///| Same as the `clear()`, but returns an cleared stack
168
///
169
/// # Example
170
///
171
/// ```
172
///   let s = @stack.of([1, 2, 3]).return_with_clear()
173
///   assert_eq(s.length(), 0)
174
/// ```
175
pub fn[T] return_with_clear(self : Stack[T]) -> Stack[T] {
176
  self.clear()
2✔
177
  self
178
}
179

180
///|
181
test "return_with_clear" {
182
  let s = of([1, 2, 3]).return_with_clear()
183
  inspect(s, content="Stack::[]")
184
}
185

186
///| Push an element into the stack.
187
/// 
188
/// # Example
189
///
190
/// ```
191
///   let s = @stack.new()
192
///   s.push(1)
193
///   assert_eq(s.length(), 1)
194
/// ```
195
pub fn[T] push(self : Stack[T], x : T) -> Unit {
196
  self.elements = Cons(x, self.elements)
23✔
197
  self.len = self.len + 1
198
}
199

200
///|
201
test "push" {
202
  let s = new()
203
  s.push(1)
204
  inspect(s, content="Stack::[1]")
205
  inspect(s.len, content="1")
206
}
207

208
///| Push a list into the stack.
209
/// 
210
/// # Example
211
///
212
/// ```
213
///   let s = @stack.new()
214
///   s.push_list(@immut/list.of([1, 2, 3]))
215
///   assert_eq(s.length(), 3)
216
/// ```
217
pub fn[T] push_list(self : Stack[T], list : @immut/list.T[T]) -> Unit {
218
  list.each(fn(i) { self.push(i) })
2✔
219
}
220

221
///|
222
test "push_list" {
223
  let s = new()
224
  s.push_list(@immut/list.of([1, 2, 3]))
225
  inspect(s, content="Stack::[3, 2, 1]")
226
  inspect(s.len, content="3")
227
}
228

229
///| Push other stack into the current stack.
230
/// 
231
/// # Example
232
///
233
/// ```
234
///   let s = @stack.of([1, 2, 3])
235
///   let s1 : Stack[Int] = @stack.new()
236
///   s1.push_stack(s)
237
///   assert_eq(s1.length(), 3)
238
/// ```
239
pub fn[T] push_stack(self : Stack[T], stack : Stack[T]) -> Unit {
240
  stack.elements.each(fn(i) { self.push(i) })
2✔
241
}
242

243
///|
244
test "push_stack" {
245
  let s = of([1, 2, 3])
246
  let s1 : Stack[Int] = new()
247
  s1.push_stack(s)
248
  inspect(s1, content="Stack::[3, 2, 1]")
249
  inspect(s.len == s1.len, content="true")
250
}
251

252
///| Push an array into the stack.
253
/// 
254
/// # Example
255
///
256
/// ```
257
///   let s : Stack[Int] = @stack.new()
258
///   s.push_array([1, 2, 3])
259
///   assert_eq(s.length(), 3)
260
/// ```
261
pub fn[T] push_array(self : Stack[T], array : Array[T]) -> Unit {
262
  array.each(fn(i) { self.push(i) })
2✔
263
}
264

265
///|
266
test "push_array" {
267
  let s : Stack[Int] = new()
268
  s.push_array([1, 2, 3])
269
  inspect(s, content="Stack::[3, 2, 1]")
270
  inspect(s.len, content="3")
271
}
272

273
///| Pop an element from the top of the stack.
274
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
275
///
276
/// # Example
277
///
278
/// ```
279
///   let s = @stack.of([1, 2, 3])
280
///   let s1 : Stack[Int] = @stack.new()
281
///   assert_eq(s.pop(), Some(1))
282
///   assert_eq(s.length(), 2)
283
///   assert_eq(s1.pop(), None)
284
/// ```
285
pub fn[T] pop(self : Stack[T]) -> T? {
286
  match self.elements {
4✔
287
    Cons(hd, tl) => {
2✔
288
      self.elements = tl
289
      self.len = self.len - 1
290
      Some(hd)
291
    }
292
    Nil => None
2✔
293
  }
294
}
295

296
///|
297
test "pop" {
298
  let s = of([1, 2, 3])
299
  let s1 : Stack[Int] = new()
300
  inspect(s.pop(), content="Some(1)")
301
  inspect(s, content="Stack::[2, 3]")
302
  inspect(s.len, content="2")
303
  inspect(s1.pop(), content="None")
304
  inspect(s1, content="Stack::[]")
305
  inspect(s1.len, content="0")
306
}
307

308
///| Pop an element from the top of the stack.
309
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
310
///
311
/// @alert unsafe "Panic if the stack is empty."
312
pub fn[T] unsafe_pop(self : Stack[T]) -> T {
313
  match self.elements {
1✔
314
    Cons(hd, tl) => {
1✔
315
      self.elements = tl
316
      self.len = self.len - 1
317
      hd
318
    }
319
    Nil => abort("pop of empty stack")
×
320
  }
321
}
322

323
///|
324
test "unsafe_pop" {
325
  let s = of([1, 2, 3])
326
  inspect(s.unsafe_pop(), content="1")
327
  inspect(s, content="Stack::[2, 3]")
328
  inspect(s.len, content="2")
329
}
330

331
///| Drop the element at the top of the stack.
332
/// Like pop, but does not return elements and does nothing if the Stack is empty.
333
///
334
/// # Example
335
///
336
/// ```
337
///   let s = @stack.of([1, 2, 3])
338
///   s.drop()
339
///   assert_eq(s.length(), 2)
340
/// ```
341
pub fn[T] drop(self : Stack[T]) -> Unit {
342
  match self.elements {
2✔
343
    Cons(_hd, tl) => {
2✔
344
      self.elements = tl
345
      self.len = self.len - 1
346
    }
347
    Nil => ()
×
348
  }
349
}
350

351
///|
352
test "drop" {
353
  let s = of([1, 2, 3])
354
  s.drop()
355
  inspect(s, content="Stack::[2, 3]")
356
  inspect(s.len, content="2")
357
}
358

359
///| Drop the element at the top of the stack.
360
/// Like drop, but when the drop is successful, it returns `Ok(())`, and when it fails, it returns `Err(())`
361
///
362
/// # Example
363
///
364
/// ```
365
///   let s = @stack.of([1, 2, 3])
366
///   let r = s.drop_result() // Ok(())
367
///   assert_eq(r, Ok(()))
368
/// ```
369
pub fn[T] drop_result(self : Stack[T]) -> Result[Unit, Unit] {
370
  match self.elements {
3✔
371
    Cons(_hd, tl) => {
2✔
372
      self.elements = tl
373
      self.len = self.len - 1
374
      Ok(())
375
    }
376
    Nil => Err(())
1✔
377
  }
378
}
379

380
///|
381
test "drop_result" {
382
  let s = of([1, 2, 3])
383
  let s1 : Stack[Int] = new()
384
  inspect(s1.drop_result() == Err(()), content="true")
385
  inspect(s.drop_result() == Ok(()), content="true")
386
  inspect(s, content="Stack::[2, 3]")
387
  inspect(s.len, content="2")
388
}
389

390
///| Only the top element of the stack is returned and will not be pop or drop.
391
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
392
///
393
/// # Example
394
///
395
/// ```
396
///   let s = Stack::from_array([1, 2, 3])
397
///   assert_eq(s.peek(), Some(1))
398
///   assert_eq(s.length(), 3)
399
/// ```
400
pub fn[T] peek(self : Stack[T]) -> T? {
401
  match self.elements {
2✔
402
    Cons(hd, _) => Some(hd)
2✔
403
    Nil => None
×
404
  }
405
}
406

407
///|
408
test "peek" {
409
  let s = of([1, 2, 3])
410
  inspect(s.peek(), content="Some(1)")
411
  inspect(s, content="Stack::[1, 2, 3]")
412
  inspect(s.len, content="3")
413
}
414

415
///| Only the top element of the stack is returned and will not be pop or drop.
416
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
417
///
418
/// @alert unsafe "Panic if the stack is empty."
419
pub fn[T] peek_exn(self : Stack[T]) -> T {
420
  match self.elements {
3✔
421
    Cons(hd, _) => hd
3✔
422
    Nil => abort("top of the empty stack")
×
423
  }
424
}
425

426
///|
427
test "peek_exn" {
428
  let s : Stack[Int] = of([1, 2, 3])
429
  inspect(s.peek_exn(), content="1")
430
  inspect(s, content="Stack::[1, 2, 3]")
431
  inspect(s.len, content="3")
432
}
433

434
///| If stack is empty, return true, otherwise return false.
435
///
436
/// # Example
437
///
438
/// ```
439
///   let s = @stack.of([1, 2, 3])
440
///   assert_false(s.is_empty())
441
///   let empty : Stack[Unit] = @stack.new()
442
///   assert_true(empty.is_empty())
443
/// ```
444
pub fn[T] is_empty(self : Stack[T]) -> Bool {
445
  self.len == 0
5✔
446
}
447

448
///|
449
test "is_empty" {
450
  let empty : Stack[Unit] = new()
451
  inspect(of([1, 2, 3]).is_empty(), content="false")
452
  inspect(empty.is_empty(), content="true")
453
}
454

455
///| Returns the number of elements of the Stack
456
pub fn[T] length(self : Stack[T]) -> Int {
457
  self.len
13✔
458
}
459

460
///| Iterates over the elements of the stack from top to bottom.
461
/// 
462
/// # Example
463
/// ```
464
///   let s = @stack.of([1, 2, 3])
465
///   let mut sum = 0
466
///   s.each(fn(i) { sum = sum + i })
467
///   assert_eq(sum, 6)
468
/// ```
469
pub fn[T] each(self : Stack[T], f : (T) -> Unit) -> Unit {
470
  self.elements.each(f)
4✔
471
}
472

473
///|
474
test "iter" {
475
  let s : Stack[Int] = new()
476
  let mut sum = 0
477
  let mut sub = 0
478
  s.each(fn(i) { sum = sum + i })
479
  inspect(sum, content="0")
480
  s.push(1)
481
  s.push(2)
482
  s.push(3)
483
  inspect(s.peek_exn(), content="3")
484
  sum = 0
485
  sub = s.peek_exn()
486
  s.each(fn(i) { sum = sum + i })
487
  s.each(fn(i) { sub = sub - i }) // 3 - 3 - 2 - 1
488
  inspect(sum, content="6")
489
  inspect(sub, content="-3")
490
}
491

492
///| Folds over the elements of the stack from top to bottom.
493
/// 
494
/// # Example
495
/// ```
496
///   let s = @stack.of([1, 2, 3])
497
///   let sum = s.fold(init=0, fn(acc, i) { acc + i })
498
///   assert_eq(sum, 6)
499
/// ```
500
pub fn[T, U] fold(self : Stack[T], init~ : U, f : (U, T) -> U) -> U {
501
  self.elements.fold(init~, f)
2✔
502
}
503

504
///|
505
test "fold" {
506
  let s = of([1, 2, 3])
507
  let sum = s.fold(init=0, fn(acc, i) { acc + i })
508
  inspect(sum, content="6")
509
}
510

511
///| Convert stack to list.
512
///
513
/// # Example
514
///
515
/// ```
516
///   assert_eq(@stack.of([1, 2, 3]).to_list(), @immut/list.of([1, 2, 3]))
517
/// ```
518
pub fn[T] to_list(self : Stack[T]) -> @immut/list.T[T] {
519
  self.elements
2✔
520
}
521

522
///|
523
test "to_list" {
524
  inspect(of([3, 2, 1]).to_list(), content="@list.of([3, 2, 1])")
525
}
526

527
///| Convert stack to array.
528
///
529
/// # Example
530
///
531
/// ```
532
///   assert_eq(@stack.of([1, 2, 3]).to_array(), [1, 2, 3])
533
/// ```
534
pub fn[T] to_array(self : Stack[T]) -> Array[T] {
535
  self.elements.to_array()
2✔
536
}
537

538
///|
539
test "to_array" {
540
  inspect(of([3, 2, 1]).to_array(), content="[3, 2, 1]")
541
}
542

543
///| Compare two stacks.
544
///
545
/// NOTE: Since the current standard library @immut/list.T lacks the equal or op_equal function, 
546
/// this function internally implements the equal function of @immut/list.T.
547
///
548
/// # Example
549
///
550
/// ```
551
///   assert_true(@stack.of([2, 4, 6]).equal(@stack.of([2, 4, 6])))
552
/// ```
553
pub fn[T : Eq] equal(self : Stack[T], other : Stack[T]) -> Bool {
554
  if self.len == other.len {
3✔
555
    self.elements == other.elements
3✔
556
  } else {
557
    false
×
558
  }
559
}
560

561
///|
562
pub fn[T : Eq] op_equal(self : Stack[T], other : Stack[T]) -> Bool {
563
  self.equal(other)
×
564
}
565

566
///|
567
test "equal" {
568
  inspect(of([2, 4, 6]).equal(of([2, 4, 6])), content="true")
569
  inspect(of([2, 4, 6]).equal(of([2, 4, 7])), content="false")
570
}
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