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

moonbitlang / x / 301

10 Dec 2024 06:19AM UTC coverage: 85.204% (-2.6%) from 87.841%
301

Pull #78

github

web-flow
Merge b830031f4 into 91f0fdf48
Pull Request #78: feat: new package encoding

105 of 161 new or added lines in 3 files covered. (65.22%)

124 existing lines in 29 files now uncovered.

1169 of 1372 relevant lines covered (85.2%)

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

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

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

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

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

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

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

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

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

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

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

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

202
test "push_list" {
203
  let s = Stack::new()
204
  s.push_list(@immut/list.of([1, 2, 3]))
205
  inspect!(s, content="Stack::[3, 2, 1]")
206
  inspect!(s.len, content="3")
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
/// println(s1) // Stack::[1, 2, 3]
218
/// ```
219
pub fn push_stack[T](self : Stack[T], stack : Stack[T]) -> Unit {
220
  stack.elements.each(fn(i) { self.push(i) })
1✔
221
}
222

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

541
///|
542
pub fn op_equal[T : Eq](self : Stack[T], other : Stack[T]) -> Bool {
UNCOV
543
  self.equal(other)
×
544
}
545

546
test "equal" {
547
  inspect!(Stack::of([2, 4, 6]).equal(Stack::of([2, 4, 6])), content="true")
548
  inspect!(Stack::of([2, 4, 6]).equal(Stack::of([2, 4, 7])), content="false")
549
}
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