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

moonbitlang / x / 608

04 Sep 2025 06:43AM UTC coverage: 90.99%. Remained the same
608

push

github

peter-jerry-ye
chore: update changelog and bump version

1939 of 2131 relevant lines covered (90.99%)

411.64 hits per line

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

92.68
/stack/stack.mbt
1
// Copyright 2025 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
///|
16
/// Create an empty stack.
17
///
18
/// # Example
19
///
20
/// ```
21
/// let s : Stack[Int] = @stack.new()
22
/// assert_true(s.is_empty())
23
/// ```
24
pub fnalias Stack::new
25

26
///|
27
/// Create an empty stack.
28
///
29
/// # Example
30
///
31
/// ```
32
/// let s : Stack[Int] = @stack.Stack::new()
33
/// assert_true(s.is_empty())
34
/// ```
35
pub fn[T] Stack::new() -> Stack[T] {
36
  { elements: @list.from_array([]), len: 0 }
22✔
37
}
38

39
///|
40
test "new" {
41
  let s : Stack[Int] = new()
42
  inspect(s, content="Stack::[]")
43
}
44

45
///|
46
/// Create a stack based on all elements in array.
47
///
48
/// # Example
49
///
50
/// ```
51
///   let s = Stack::from_array([1, 2, 3])
52
///   assert_eq(s.length(), 3)
53
/// ```
54
pub fn[T] Stack::from_array(array : Array[T]) -> Stack[T] {
55
  { elements: @list.from_array(array), len: array.length() }
5✔
56
}
57

58
///|
59
test "from_array" {
60
  let s = Stack::from_array([1, 2, 3])
61
  inspect(s, content="Stack::[1, 2, 3]")
62
  inspect(s.len, content="3")
63
}
64

65
///|
66
pub fn[T] Stack::from_iter(iter : Iter[T]) -> Stack[T] {
67
  let mut len = 0
1✔
68
  let elements = @list.from_iter(iter.tap(_ => len += 1))
1✔
69
  { elements, len }
70
}
71

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

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

92
///|
93
pub fnalias Stack::of
94

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

101
///|
102
pub impl[T : Show] Show for Stack[T] with output(self, logger : &Logger) -> Unit {
103
  logger.write_string("Stack::[")
23✔
104
  let mut i = 0
105
  self.elements.each(fn(t) {
23✔
106
    if i > 0 {
43✔
107
      logger.write_string(", ")
27✔
108
    }
109
    t.output(logger)
43✔
110
    i = i + 1
111
  })
112
  logger.write_string("]")
23✔
113
}
114

115
///|
116
test "to_string" {
117
  let empty : Stack[Int] = new()
118
  inspect(empty, content="Stack::[]")
119
  inspect(of([1, 2, 3, 4, 5]), content="Stack::[1, 2, 3, 4, 5]")
120
}
121

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

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

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

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

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

179
///|
180
test "return_with_clear" {
181
  let s = of([1, 2, 3]).return_with_clear()
182
  inspect(s, content="Stack::[]")
183
}
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 = @list.construct(x, self.elements)
26✔
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
///|
209
/// Push other stack into the current stack.
210
/// 
211
/// # Example
212
///
213
/// ```
214
///   let s = @stack.of([1, 2, 3])
215
///   let s1 : Stack[Int] = @stack.new()
216
///   s1.push_stack(s)
217
///   assert_eq(s1.length(), 3)
218
/// ```
219
pub fn[T] push_stack(self : Stack[T], stack : Stack[T]) -> Unit {
220
  stack.elements.iter().each(fn(i) { self.push(i) })
2✔
221
}
222

223
///|
224
test "push_stack" {
225
  let s = of([1, 2, 3])
226
  let s1 : Stack[Int] = new()
227
  s1.push_stack(s)
228
  inspect(s1, content="Stack::[3, 2, 1]")
229
  inspect(s.length() == s1.length(), content="true")
230
}
231

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

246
///|
247
test "push_array" {
248
  let s : Stack[Int] = new()
249
  s.push_array([1, 2, 3])
250
  inspect(s, content="Stack::[3, 2, 1]")
251
  inspect(s.len, content="3")
252
}
253

254
///|
255
/// Pop an element from the top of the stack.
256
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
257
///
258
/// # Example
259
///
260
/// ```
261
///   let s = @stack.of([1, 2, 3])
262
///   let s1 : Stack[Int] = @stack.new()
263
///   assert_eq(s.pop(), Some(1))
264
///   assert_eq(s.length(), 2)
265
///   assert_eq(s1.pop(), None)
266
/// ```
267
pub fn[T] pop(self : Stack[T]) -> T? {
268
  match self.elements {
5✔
269
    More(hd, tail=tl) => {
3✔
270
      self.elements = tl
271
      self.len = self.len - 1
272
      Some(hd)
273
    }
274
    Empty => None
2✔
275
  }
276
}
277

278
///|
279
test "pop" {
280
  let s = of([1, 2, 3])
281
  let s1 : Stack[Int] = new()
282
  inspect(s.pop(), content="Some(1)")
283
  inspect(s, content="Stack::[2, 3]")
284
  inspect(s.len, content="2")
285
  inspect(s1.pop(), content="None")
286
  inspect(s1, content="Stack::[]")
287
  inspect(s1.len, content="0")
288
}
289

290
///|
291
/// Pop an element from the top of the stack.
292
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
293
///
294
/// @alert unsafe "Panic if the stack is empty."
295
pub fn[T] unsafe_pop(self : Stack[T]) -> T {
296
  match self.elements {
3✔
297
    More(hd, tail=tl) => {
2✔
298
      self.elements = tl
299
      self.len = self.len - 1
300
      hd
301
    }
302
    Empty => abort("pop of empty stack")
1✔
303
  }
304
}
305

306
///|
307
test "unsafe_pop" {
308
  let s = 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
///|
315
/// Drop the element at the top of the stack.
316
/// Like pop, but does not return elements and does nothing if the Stack is empty.
317
///
318
/// # Example
319
///
320
/// ```
321
///   let s = @stack.of([1, 2, 3])
322
///   s.drop()
323
///   assert_eq(s.length(), 2)
324
/// ```
325
pub fn[T] drop(self : Stack[T]) -> Unit {
326
  match self.elements {
3✔
327
    More(_hd, tail=tl) => {
3✔
328
      self.elements = tl
329
      self.len = self.len - 1
330
    }
331
    Empty => ()
×
332
  }
333
}
334

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

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

365
///|
366
test "drop_result" {
367
  let s = of([1, 2, 3])
368
  let s1 : Stack[Int] = new()
369
  inspect(s1.drop_result() == Err(()), content="true")
370
  inspect(s.drop_result() == Ok(()), content="true")
371
  inspect(s, content="Stack::[2, 3]")
372
  inspect(s.len, content="2")
373
}
374

375
///|
376
/// Only the top element of the stack is returned and will not be pop or drop.
377
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
378
///
379
/// # Example
380
///
381
/// ```
382
///   let s = Stack::from_array([1, 2, 3])
383
///   assert_eq(s.peek(), Some(1))
384
///   assert_eq(s.length(), 3)
385
/// ```
386
pub fn[T] peek(self : Stack[T]) -> T? {
387
  self.elements.head()
3✔
388
}
389

390
///|
391
test "peek" {
392
  let s = of([1, 2, 3])
393
  inspect(s.peek(), content="Some(1)")
394
  inspect(s, content="Stack::[1, 2, 3]")
395
  inspect(s.len, content="3")
396
}
397

398
///|
399
/// Only the top element of the stack is returned and will not be pop or drop.
400
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
401
///
402
/// @alert unsafe "Panic if the stack is empty."
403
pub fn[T] unsafe_peek(self : Stack[T]) -> T {
404
  self.elements.unsafe_head()
4✔
405
}
406

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

415
///|
416
/// If stack is empty, return true, otherwise return false.
417
///
418
/// # Example
419
///
420
/// ```
421
///   let s = @stack.of([1, 2, 3])
422
///   assert_false(s.is_empty())
423
///   let empty : Stack[Unit] = @stack.new()
424
///   assert_true(empty.is_empty())
425
/// ```
426
pub fn[T] is_empty(self : Stack[T]) -> Bool {
427
  self.len == 0
7✔
428
}
429

430
///|
431
test "is_empty" {
432
  let empty : Stack[Unit] = new()
433
  inspect(of([1, 2, 3]).is_empty(), content="false")
434
  inspect(empty.is_empty(), content="true")
435
}
436

437
///|
438
/// Returns the number of elements of the Stack
439
pub fn[T] length(self : Stack[T]) -> Int {
440
  self.len
15✔
441
}
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
///   let mut sum = 0
450
///   s.each(fn(i) { sum = sum + i })
451
///   assert_eq(sum, 6)
452
/// ```
453
pub fn[T] each(self : Stack[T], f : (T) -> Unit) -> Unit {
454
  self.elements.iter().each(f)
4✔
455
}
456

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

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

489
///|
490
test "fold" {
491
  let s = of([1, 2, 3])
492
  let sum = s.fold(init=0, fn(acc, i) { acc + i })
493
  inspect(sum, content="6")
494
}
495

496
///|
497
/// Covert stack to an iterator.
498
/// 
499
/// # Example
500
/// ```
501
/// let stack = @stack.new()
502
/// 
503
/// stack.push(3)
504
/// stack.push(2)
505
/// stack.push(1)
506
/// inspect(stack.iter(), content="[1, 2, 3]")
507
/// ```
508
pub fn[T] iter(self : Stack[T]) -> Iter[T] {
509
  self.elements.iter()
4✔
510
}
511

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

524
///|
525
test "to_array" {
526
  inspect(of([3, 2, 1]).to_array(), content="[3, 2, 1]")
527
}
528

529
///|
530
/// Compare two stacks.
531
///
532
/// NOTE: Since the current standard library @immut/list.T lacks the equal or op_equal function, 
533
/// this function internally implements the equal function of @immut/list.T.
534
///
535
/// # Example
536
///
537
/// ```
538
///   assert_true(@stack.of([2, 4, 6]).equal(@stack.of([2, 4, 6])))
539
/// ```
540
pub fn[T : Eq] equal(self : Stack[T], other : Stack[T]) -> Bool {
541
  if self.len == other.len {
3✔
542
    self.elements == other.elements
3✔
543
  } else {
544
    false
×
545
  }
546
}
547

548
///|
549
pub fn[T : Eq] op_equal(self : Stack[T], other : Stack[T]) -> Bool {
550
  self.equal(other)
×
551
}
552

553
///|
554
test "equal" {
555
  inspect(of([2, 4, 6]).equal(of([2, 4, 6])), content="true")
556
  inspect(of([2, 4, 6]).equal(of([2, 4, 7])), content="false")
557
}
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