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

moonbitlang / x / 540

23 Jul 2025 07:25AM UTC coverage: 89.783% (+0.1%) from 89.676%
540

push

github

peter-jerry-ye
chore: add changelog

1907 of 2124 relevant lines covered (89.78%)

384.85 hits per line

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

90.24
/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
///| 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 fnalias Stack::new
24

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

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

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

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

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

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

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

88
///|
89
pub fnalias Stack::of
90

91
///|
92
test "of" {
93
  let s = of([1, 2, 3])
94
  inspect(s, content="Stack::[1, 2, 3]")
95
}
96

97
///|
98
pub impl[T : Show] Show for Stack[T] with output(self, logger : &Logger) -> Unit {
99
  logger.write_string("Stack::[")
18✔
100
  let mut i = 0
101
  self.elements.each(fn(t) {
18✔
102
    if i > 0 {
35✔
103
      logger.write_string(", ")
22✔
104
    }
105
    t.output(logger)
35✔
106
    i = i + 1
107
  })
108
  logger.write_string("]")
18✔
109
}
110

111
///|
112
test "to_string" {
113
  let empty : Stack[Int] = new()
114
  inspect(empty, content="Stack::[]")
115
  inspect(of([1, 2, 3, 4, 5]), content="Stack::[1, 2, 3, 4, 5]")
116
}
117

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

131
///|
132
test "from_stack" {
133
  let s = of([1, 2, 3])
134
  let s1 = Stack::from_stack(s)
135
  inspect(s1.elements == s.elements, content="true")
136
}
137

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

152
///|
153
test "clear" {
154
  let s = of([1, 2, 3])
155
  s.clear()
156
  inspect(s, content="Stack::[]")
157
}
158

159
///| Same as the `clear()`, but returns an cleared stack
160
///
161
/// # Example
162
///
163
/// ```
164
///   let s = @stack.of([1, 2, 3]).return_with_clear()
165
///   assert_eq(s.length(), 0)
166
/// ```
167
pub fn[T] return_with_clear(self : Stack[T]) -> Stack[T] {
168
  self.clear()
2✔
169
  self
170
}
171

172
///|
173
test "return_with_clear" {
174
  let s = of([1, 2, 3]).return_with_clear()
175
  inspect(s, content="Stack::[]")
176
}
177

178
///| Push an element into the stack.
179
/// 
180
/// # Example
181
///
182
/// ```
183
///   let s = @stack.new()
184
///   s.push(1)
185
///   assert_eq(s.length(), 1)
186
/// ```
187
pub fn[T] push(self : Stack[T], x : T) -> Unit {
188
  self.elements = @list.construct(x, self.elements)
23✔
189
  self.len = self.len + 1
190
}
191

192
///|
193
test "push" {
194
  let s = new()
195
  s.push(1)
196
  inspect(s, content="Stack::[1]")
197
  inspect(s.len, content="1")
198
}
199

200
///| Push other stack into the current stack.
201
/// 
202
/// # Example
203
///
204
/// ```
205
///   let s = @stack.of([1, 2, 3])
206
///   let s1 : Stack[Int] = @stack.new()
207
///   s1.push_stack(s)
208
///   assert_eq(s1.length(), 3)
209
/// ```
210
pub fn[T] push_stack(self : Stack[T], stack : Stack[T]) -> Unit {
211
  stack.elements.iter().each(fn(i) { self.push(i) })
2✔
212
}
213

214
///|
215
test "push_stack" {
216
  let s = of([1, 2, 3])
217
  let s1 : Stack[Int] = new()
218
  s1.push_stack(s)
219
  inspect(s1, content="Stack::[3, 2, 1]")
220
  inspect(s.length() == s1.length(), content="true")
221
}
222

223
///| Push an array into the stack.
224
/// 
225
/// # Example
226
///
227
/// ```
228
///   let s : Stack[Int] = @stack.new()
229
///   s.push_array([1, 2, 3])
230
///   assert_eq(s.length(), 3)
231
/// ```
232
pub fn[T] push_array(self : Stack[T], array : Array[T]) -> Unit {
233
  array.each(fn(i) { self.push(i) })
2✔
234
}
235

236
///|
237
test "push_array" {
238
  let s : Stack[Int] = new()
239
  s.push_array([1, 2, 3])
240
  inspect(s, content="Stack::[3, 2, 1]")
241
  inspect(s.len, content="3")
242
}
243

244
///| Pop an element from the top of the stack.
245
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
246
///
247
/// # Example
248
///
249
/// ```
250
///   let s = @stack.of([1, 2, 3])
251
///   let s1 : Stack[Int] = @stack.new()
252
///   assert_eq(s.pop(), Some(1))
253
///   assert_eq(s.length(), 2)
254
///   assert_eq(s1.pop(), None)
255
/// ```
256
pub fn[T] pop(self : Stack[T]) -> T? {
257
  match self.elements {
4✔
258
    More(hd, tail=tl) => {
2✔
259
      self.elements = tl
260
      self.len = self.len - 1
261
      Some(hd)
262
    }
263
    Empty => None
2✔
264
  }
265
}
266

267
///|
268
test "pop" {
269
  let s = of([1, 2, 3])
270
  let s1 : Stack[Int] = new()
271
  inspect(s.pop(), content="Some(1)")
272
  inspect(s, content="Stack::[2, 3]")
273
  inspect(s.len, content="2")
274
  inspect(s1.pop(), content="None")
275
  inspect(s1, content="Stack::[]")
276
  inspect(s1.len, content="0")
277
}
278

279
///| Pop an element from the top of the stack.
280
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
281
///
282
/// @alert unsafe "Panic if the stack is empty."
283
pub fn[T] unsafe_pop(self : Stack[T]) -> T {
284
  match self.elements {
1✔
285
    More(hd, tail=tl) => {
1✔
286
      self.elements = tl
287
      self.len = self.len - 1
288
      hd
289
    }
290
    Empty => abort("pop of empty stack")
×
291
  }
292
}
293

294
///|
295
test "unsafe_pop" {
296
  let s = of([1, 2, 3])
297
  inspect(s.unsafe_pop(), content="1")
298
  inspect(s, content="Stack::[2, 3]")
299
  inspect(s.len, content="2")
300
}
301

302
///| Drop the element at the top of the stack.
303
/// Like pop, but does not return elements and does nothing if the Stack is empty.
304
///
305
/// # Example
306
///
307
/// ```
308
///   let s = @stack.of([1, 2, 3])
309
///   s.drop()
310
///   assert_eq(s.length(), 2)
311
/// ```
312
pub fn[T] drop(self : Stack[T]) -> Unit {
313
  match self.elements {
2✔
314
    More(_hd, tail=tl) => {
2✔
315
      self.elements = tl
316
      self.len = self.len - 1
317
    }
318
    Empty => ()
×
319
  }
320
}
321

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

330
///| Drop the element at the top of the stack.
331
/// Like drop, but when the drop is successful, it returns `Ok(())`, and when it fails, it returns `Err(())`
332
///
333
/// # Example
334
///
335
/// ```
336
///   let s = @stack.of([1, 2, 3])
337
///   let r = s.drop_result() // Ok(())
338
///   assert_eq(r, Ok(()))
339
/// ```
340
pub fn[T] drop_result(self : Stack[T]) -> Result[Unit, Unit] {
341
  match self.elements {
3✔
342
    More(_hd, tail=tl) => {
2✔
343
      self.elements = tl
344
      self.len = self.len - 1
345
      Ok(())
346
    }
347
    Empty => Err(())
1✔
348
  }
349
}
350

351
///|
352
test "drop_result" {
353
  let s = of([1, 2, 3])
354
  let s1 : Stack[Int] = new()
355
  inspect(s1.drop_result() == Err(()), content="true")
356
  inspect(s.drop_result() == Ok(()), content="true")
357
  inspect(s, content="Stack::[2, 3]")
358
  inspect(s.len, content="2")
359
}
360

361
///| Only the top element of the stack is returned and will not be pop or drop.
362
/// If there are elements in the stack, return `Some (the top element of the stack)`, otherwise return `None`.
363
///
364
/// # Example
365
///
366
/// ```
367
///   let s = Stack::from_array([1, 2, 3])
368
///   assert_eq(s.peek(), Some(1))
369
///   assert_eq(s.length(), 3)
370
/// ```
371
pub fn[T] peek(self : Stack[T]) -> T? {
372
  self.elements.head()
2✔
373
}
374

375
///|
376
test "peek" {
377
  let s = of([1, 2, 3])
378
  inspect(s.peek(), content="Some(1)")
379
  inspect(s, content="Stack::[1, 2, 3]")
380
  inspect(s.len, content="3")
381
}
382

383
///| Only the top element of the stack is returned and will not be pop or drop.
384
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
385
///
386
/// @alert unsafe "Panic if the stack is empty."
387
pub fn[T] peek_exn(self : Stack[T]) -> T {
388
  self.elements.unsafe_head()
3✔
389
}
390

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

399
///| If stack is empty, return true, otherwise return false.
400
///
401
/// # Example
402
///
403
/// ```
404
///   let s = @stack.of([1, 2, 3])
405
///   assert_false(s.is_empty())
406
///   let empty : Stack[Unit] = @stack.new()
407
///   assert_true(empty.is_empty())
408
/// ```
409
pub fn[T] is_empty(self : Stack[T]) -> Bool {
410
  self.len == 0
6✔
411
}
412

413
///|
414
test "is_empty" {
415
  let empty : Stack[Unit] = new()
416
  inspect(of([1, 2, 3]).is_empty(), content="false")
417
  inspect(empty.is_empty(), content="true")
418
}
419

420
///| Returns the number of elements of the Stack
421
pub fn[T] length(self : Stack[T]) -> Int {
422
  self.len
14✔
423
}
424

425
///| Iterates over the elements of the stack from top to bottom.
426
/// 
427
/// # Example
428
/// ```
429
///   let s = @stack.of([1, 2, 3])
430
///   let mut sum = 0
431
///   s.each(fn(i) { sum = sum + i })
432
///   assert_eq(sum, 6)
433
/// ```
434
pub fn[T] each(self : Stack[T], f : (T) -> Unit) -> Unit {
435
  self.elements.iter().each(f)
4✔
436
}
437

438
///|
439
test "iter" {
440
  let s : Stack[Int] = new()
441
  let mut sum = 0
442
  let mut sub = 0
443
  s.each(fn(i) { sum = sum + i })
444
  inspect(sum, content="0")
445
  s.push(1)
446
  s.push(2)
447
  s.push(3)
448
  inspect(s.peek_exn(), content="3")
449
  sum = 0
450
  sub = s.peek_exn()
451
  s.each(fn(i) { sum = sum + i })
452
  s.each(fn(i) { sub = sub - i }) // 3 - 3 - 2 - 1
453
  inspect(sum, content="6")
454
  inspect(sub, content="-3")
455
}
456

457
///| Folds over the elements of the stack from top to bottom.
458
/// 
459
/// # Example
460
/// ```
461
///   let s = @stack.of([1, 2, 3])
462
///   let sum = s.fold(init=0, fn(acc, i) { acc + i })
463
///   assert_eq(sum, 6)
464
/// ```
465
pub fn[T, U] fold(self : Stack[T], init~ : U, f : (U, T) -> U) -> U {
466
  self.elements.fold(init~, f)
2✔
467
}
468

469
///|
470
test "fold" {
471
  let s = of([1, 2, 3])
472
  let sum = s.fold(init=0, fn(acc, i) { acc + i })
473
  inspect(sum, content="6")
474
}
475

476
///|
477
/// Covert stack to an iterator.
478
/// 
479
/// # Example
480
/// ```
481
/// let stack = @stack.new()
482
/// 
483
/// stack.push(3)
484
/// stack.push(2)
485
/// stack.push(1)
486
/// inspect(stack.iter(), content="[1, 2, 3]")
487
/// ```
488
pub fn[T] iter(self : Stack[T]) -> Iter[T] {
489
  self.elements.iter()
1✔
490
}
491

492
///| Convert stack to array.
493
///
494
/// # Example
495
///
496
/// ```
497
///   assert_eq(@stack.of([1, 2, 3]).to_array(), [1, 2, 3])
498
/// ```
499
pub fn[T] to_array(self : Stack[T]) -> Array[T] {
500
  self.elements.to_array()
2✔
501
}
502

503
///|
504
test "to_array" {
505
  inspect(of([3, 2, 1]).to_array(), content="[3, 2, 1]")
506
}
507

508
///| Compare two stacks.
509
///
510
/// NOTE: Since the current standard library @immut/list.T lacks the equal or op_equal function, 
511
/// this function internally implements the equal function of @immut/list.T.
512
///
513
/// # Example
514
///
515
/// ```
516
///   assert_true(@stack.of([2, 4, 6]).equal(@stack.of([2, 4, 6])))
517
/// ```
518
pub fn[T : Eq] equal(self : Stack[T], other : Stack[T]) -> Bool {
519
  if self.len == other.len {
3✔
520
    self.elements == other.elements
3✔
521
  } else {
522
    false
×
523
  }
524
}
525

526
///|
527
pub fn[T : Eq] op_equal(self : Stack[T], other : Stack[T]) -> Bool {
528
  self.equal(other)
×
529
}
530

531
///|
532
test "equal" {
533
  inspect(of([2, 4, 6]).equal(of([2, 4, 6])), content="true")
534
  inspect(of([2, 4, 6]).equal(of([2, 4, 7])), content="false")
535
}
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