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

moonbitlang / x / 387

10 Mar 2025 10:05AM UTC coverage: 88.472% (-1.1%) from 89.592%
387

Pull #112

github

web-flow
Merge f19595cde into 2fdae536b
Pull Request #112: perf(encoding): optimize char accumulation

2 of 19 new or added lines in 2 files covered. (10.53%)

9 existing lines in 1 file now uncovered.

1274 of 1440 relevant lines covered (88.47%)

429.39 hits per line

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

80.0
/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 new[T]() -> Stack[T] {
24
  { elements: Nil, len: 0 }
10✔
25
}
26

27
///|
28
#deprecated("use `@stack.new()` instead")
29
pub fn Stack::new[T]() -> Stack[T] {
UNCOV
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
/// println(s) // Stack::[1, 2, 3]
46
/// ```
47
pub fn Stack::from_list[T](list : @immut/list.T[T]) -> Stack[T] {
48
  { elements: list, len: list.length() }
1✔
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
/// println(s) // Stack::from_array([3, 2, 1])
65
/// ```
66
pub fn Stack::from_array[T](array : Array[T]) -> Stack[T] {
67
  { elements: @immut/list.from_array(array), len: array.length() }
1✔
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
/// println(s) // Stack::of([3, 2, 1])
84
/// ```
85
#deprecated("use `@stack.of()` instead")
86
pub fn Stack::of[T](array : FixedArray[T]) -> Stack[T] {
UNCOV
87
  { elements: @immut/list.of(array), len: array.length() }
×
88
}
89

90
///|
91
pub fn of[T](array : FixedArray[T]) -> Stack[T] {
92
  { elements: @immut/list.of(array), len: array.length() }
20✔
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 to_string[T : Show](self : Stack[T]) -> String {
104
  let mut res = "Stack::["
19✔
105
  self.elements.eachi(fn(i, t) {
106
    if i > 0 {
38✔
107
      res += ", "
24✔
108
    }
109
    res += t.to_string()
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
/// println(s1) // output: Stack::[3, 2, 1]
134
/// ```
135
pub fn Stack::from_stack[T](other : Stack[T]) -> Stack[T] {
136
  { ..other }
1✔
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
/// println(s) // Stack::[]
154
/// ```
155
pub fn clear[T](self : Stack[T]) -> Unit {
156
  self.elements = Nil
2✔
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
/// println(s) // Stack::[]
174
/// ```
175
pub fn return_with_clear[T](self : Stack[T]) -> Stack[T] {
176
  self.clear()
1✔
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
/// println(s) // Stack::[1]
194
/// ```
195
pub fn push[T](self : Stack[T], x : T) -> Unit {
196
  self.elements = Cons(x, self.elements)
13✔
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
/// println(s) // Stack::[3, 2, 1]
216
/// ```
217
pub fn push_list[T](self : Stack[T], list : @immut/list.T[T]) -> Unit {
218
  list.each(fn(i) { self.push(i) })
1✔
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
/// println(s1) // Stack::[1, 2, 3]
238
/// ```
239
pub fn push_stack[T](self : Stack[T], stack : Stack[T]) -> Unit {
240
  stack.elements.each(fn(i) { self.push(i) })
1✔
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
/// println(s) // Stack::[3, 2, 1]
260
/// ```
261
pub fn push_array[T](self : Stack[T], array : Array[T]) -> Unit {
262
  array.each(fn(i) { self.push(i) })
1✔
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
/// println(s.pop()) // Some(1)
282
/// println(s) // Stack::[2, 3]
283
/// println(s1.pop()) // None
284
/// ```
285
pub fn pop[T](self : Stack[T]) -> T? {
286
  match self.elements {
2✔
287
    Cons(hd, tl) => {
1✔
288
      self.elements = tl
289
      self.len = self.len - 1
290
      Some(hd)
291
    }
292
    Nil => None
1✔
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
/// # Example
312
///
313
/// ```
314
/// let s = Stack::of([1, 2, 3])
315
/// let s1 : Stack[Int] = Stack::new()
316
/// println(s.unsafe_pop()) // 1
317
/// println(s) // Stack::[2, 3]
318
/// println(s1.unsafe_pop()) // abort.
319
/// ```
320
/// @alert unsafe "Panic if the stack is empty."
321
pub fn unsafe_pop[T](self : Stack[T]) -> T {
322
  match self.elements {
1✔
323
    Cons(hd, tl) => {
1✔
324
      self.elements = tl
325
      self.len = self.len - 1
326
      hd
327
    }
UNCOV
328
    Nil => abort("pop of empty stack")
×
329
  }
330
}
331

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

340
///| Drop the element at the top of the stack.
341
/// Like pop, but does not return elements and does nothing if the Stack is empty.
342
///
343
/// # Example
344
///
345
/// ```
346
/// let s = Stack::of([1, 2, 3])
347
/// s.drop()
348
/// println(s) // Stack::[2, 3]
349
/// ```
350
pub fn drop[T](self : Stack[T]) -> Unit {
351
  match self.elements {
1✔
352
    Cons(_hd, tl) => {
1✔
353
      self.elements = tl
354
      self.len = self.len - 1
355
    }
UNCOV
356
    Nil => ()
×
357
  }
358
}
359

360
///|
361
test "drop" {
362
  let s = of([1, 2, 3])
363
  s.drop()
364
  inspect!(s, content="Stack::[2, 3]")
365
  inspect!(s.len, content="2")
366
}
367

368
///| Drop the element at the top of the stack.
369
/// Like drop, but when the drop is successful, it returns `Ok(())`, and when it fails, it returns `Err(())`
370
///
371
/// # Example
372
///
373
/// ```
374
/// let s = Stack::of([1, 2, 3])
375
/// let r = s.drop_result() // Ok(())
376
/// ```
377
pub fn drop_result[T](self : Stack[T]) -> Result[Unit, Unit] {
378
  match self.elements {
2✔
379
    Cons(_hd, tl) => {
1✔
380
      self.elements = tl
381
      self.len = self.len - 1
382
      Ok(())
383
    }
384
    Nil => Err(())
1✔
385
  }
386
}
387

388
///|
389
test "drop_result" {
390
  let s = of([1, 2, 3])
391
  let s1 : Stack[Int] = new()
392
  inspect!(s1.drop_result() == Err(()), content="true")
393
  inspect!(s.drop_result() == Ok(()), content="true")
394
  inspect!(s, content="Stack::[2, 3]")
395
  inspect!(s.len, content="2")
396
}
397

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

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

423
///| Only the top element of the stack is returned and will not be pop or drop.
424
/// If there are elements in the stack, return the top element of the stack, otherwise abort.
425
///
426
/// # Example
427
///
428
/// ```
429
/// let s = Stack::from_array([1, 2, 3])
430
/// let s1 : Stack[Int] = Stack::new()
431
/// println(s1.peek_exn()) // abort
432
/// println(s.peek_exn()) // 1
433
/// println(s) // Stack::[1, 2, 3]
434
/// ```
435
/// @alert unsafe "Panic if the stack is empty."
436
pub fn peek_exn[T](self : Stack[T]) -> T {
437
  match self.elements {
3✔
438
    Cons(hd, _) => hd
3✔
UNCOV
439
    Nil => abort("top of the empty stack")
×
440
  }
441
}
442

443
///|
444
test "peek_exn" {
445
  let s : Stack[Int] = of([1, 2, 3])
446
  inspect!(s.peek_exn(), content="1")
447
  inspect!(s, content="Stack::[1, 2, 3]")
448
  inspect!(s.len, content="3")
449
}
450

451
///| If stack is empty, return true, otherwise return false.
452
///
453
/// # Example
454
///
455
/// ```
456
/// println(Stack::of([1, 2, 3]).is_empty()) // false
457
/// println(Stack::new().is_empty()) // true
458
/// ```
459
pub fn is_empty[T](self : Stack[T]) -> Bool {
460
  self.len == 0
2✔
461
}
462

463
///|
464
test "is_empty" {
465
  let empty : Stack[Unit] = new()
466
  inspect!(of([1, 2, 3]).is_empty(), content="false")
467
  inspect!(empty.is_empty(), content="true")
468
}
469

470
///| Returns the number of elements of the Stack
471
pub fn length[T](self : Stack[T]) -> Int {
UNCOV
472
  self.len
×
473
}
474

475
///| Iterates over the elements of the stack from top to bottom.
476
/// 
477
/// # Example
478
/// ```
479
/// let s = Stack::of([1, 2, 3])
480
/// s.each(fn(i) { println(i) })'
481
/// ```
482
pub fn each[T](self : Stack[T], f : (T) -> Unit) -> Unit {
483
  self.elements.each(f)
3✔
484
}
485

486
///|
487
test "iter" {
488
  let s : Stack[Int] = new()
489
  let mut sum = 0
490
  let mut sub = 0
491
  s.each(fn(i) { sum = sum + i })
492
  inspect!(sum, content="0")
493
  s.push(1)
494
  s.push(2)
495
  s.push(3)
496
  inspect!(s.peek_exn(), content="3")
497
  sum = 0
498
  sub = s.peek_exn()
499
  s.each(fn(i) { sum = sum + i })
500
  s.each(fn(i) { sub = sub - i }) // 3 - 3 - 2 - 1
501
  inspect!(sum, content="6")
502
  inspect!(sub, content="-3")
503
}
504

505
///| Folds over the elements of the stack from top to bottom.
506
/// 
507
/// # Example
508
/// ```
509
/// let s = Stack::of([1, 2, 3])
510
/// let sum = s.fold(~init=0, fn(acc, i) { acc + i })
511
/// println(sum) // 6
512
/// ```
513
pub fn fold[T, U](self : Stack[T], init~ : U, f : (U, T) -> U) -> U {
514
  self.elements.fold(init~, f)
1✔
515
}
516

517
///|
518
test "fold" {
519
  let s = of([1, 2, 3])
520
  let sum = s.fold(init=0, fn(acc, i) { acc + i })
521
  inspect!(sum, content="6")
522
}
523

524
///| Convert stack to list.
525
///
526
/// # Example
527
///
528
/// ```
529
/// println(Stack::of([1, 2, 3]).to_list()) // @immut/list.of([1, 2, 3])
530
/// ```
531
pub fn to_list[T](self : Stack[T]) -> @immut/list.T[T] {
532
  self.elements
1✔
533
}
534

535
///|
536
test "to_list" {
537
  inspect!(of([3, 2, 1]).to_list(), content="@list.of([3, 2, 1])")
538
}
539

540
///| Convert stack to array.
541
///
542
/// # Example
543
///
544
/// ```
545
/// println(Stack::of([1, 2, 3]).to_array()) // [1, 2, 3]
546
/// ```
547
pub fn to_array[T : Default](self : Stack[T]) -> Array[T] {
548
  self.elements.to_array()
1✔
549
}
550

551
///|
552
test "to_array" {
553
  inspect!(of([3, 2, 1]).to_array(), content="[3, 2, 1]")
554
}
555

556
///| Compare two stacks.
557
///
558
/// NOTE: Since the current standard library @immut/list.T lacks the equal or op_equal function, 
559
/// this function internally implements the equal function of @immut/list.T.
560
///
561
/// # Example
562
///
563
/// ```
564
/// println(Stack::of([2, 4, 6]).equal(Stack::of([2, 4, 6]))) // true
565
/// ```
566
pub fn equal[T : Eq](self : Stack[T], other : Stack[T]) -> Bool {
567
  if self.len == other.len {
2✔
568
    self.elements == other.elements
2✔
569
  } else {
UNCOV
570
    false
×
571
  }
572
}
573

574
///|
575
pub fn op_equal[T : Eq](self : Stack[T], other : Stack[T]) -> Bool {
UNCOV
576
  self.equal(other)
×
577
}
578

579
///|
580
test "equal" {
581
  inspect!(of([2, 4, 6]).equal(of([2, 4, 6])), content="true")
582
  inspect!(of([2, 4, 6]).equal(of([2, 4, 7])), content="false")
583
}
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