Skip to content

Commit 6a9d331

Browse files
authored
data_structure: add stack implementation (#67)
1 parent 972616a commit 6a9d331

3 files changed

Lines changed: 112 additions & 0 deletions

File tree

.github/workflows/tests.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ jobs:
1515
directory: .
1616
add-to-path: true
1717

18+
- name: Test - data_structures
19+
run: |
20+
julec test -o test data_structures
21+
git update-index --add --chmod=-x test
22+
chmod +x test
23+
./test
24+
1825
- name: Test - math
1926
run: |
2027
julec test -o test math

data_structures/stack.jule

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// Implementation of a generic LIFO (last-in, first-out) stack.
2+
// Reference: https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
3+
4+
// Stack is a generic last-in, first-out (LIFO) collection.
5+
struct Stack[T] {
6+
items: []T
7+
}
8+
9+
impl Stack {
10+
// Push adds an item to the top of the stack.
11+
fn Push(mut *self, item: T) {
12+
self.items = append(self.items, item)
13+
}
14+
15+
// Pop removes and returns the item at the top of the stack.
16+
// The second return value reports whether an item was removed;
17+
// it is false when the stack is empty.
18+
fn Pop(mut *self): (item: T, ok: bool) {
19+
if len(self.items) == 0 {
20+
return
21+
}
22+
last := len(self.items) - 1
23+
item = self.items[last]
24+
self.items = self.items[:last]
25+
ok = true
26+
return
27+
}
28+
29+
// Peek returns the item at the top of the stack without removing it.
30+
// The second return value reports whether the stack has an item;
31+
// it is false when the stack is empty.
32+
fn Peek(*self): (item: T, ok: bool) {
33+
if len(self.items) == 0 {
34+
return
35+
}
36+
item = self.items[len(self.items)-1]
37+
ok = true
38+
return
39+
}
40+
41+
// Len returns the number of items in the stack.
42+
fn Len(*self): int {
43+
return len(self.items)
44+
}
45+
46+
// Empty reports whether the stack has no items.
47+
fn Empty(*self): bool {
48+
return len(self.items) == 0
49+
}
50+
}

data_structures/stack_test.jule

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#build test
2+
3+
use "std/testing"
4+
5+
#test
6+
fn testStackPushPop(t: &testing::T) {
7+
mut s := Stack[int]{}
8+
t.Assert(s.Empty(), "new stack should be empty")
9+
t.Assert(s.Len() == 0, "new stack should have length 0")
10+
11+
s.Push(1)
12+
s.Push(2)
13+
s.Push(3)
14+
t.Assert(!s.Empty(), "stack with items should not be empty")
15+
t.Assert(s.Len() == 3, "stack should have length 3")
16+
17+
v1, ok1 := s.Pop()
18+
t.Assert(ok1 && v1 == 3, "pop should return the last pushed item (3)")
19+
20+
v2, ok2 := s.Pop()
21+
t.Assert(ok2 && v2 == 2, "pop should return 2")
22+
23+
v3, ok3 := s.Pop()
24+
t.Assert(ok3 && v3 == 1, "pop should return 1")
25+
26+
t.Assert(s.Empty(), "stack should be empty after popping all items")
27+
}
28+
29+
#test
30+
fn testStackPopEmpty(t: &testing::T) {
31+
mut s := Stack[int]{}
32+
_, ok := s.Pop()
33+
t.Assert(!ok, "pop on empty stack should report ok == false")
34+
}
35+
36+
#test
37+
fn testStackPeek(t: &testing::T) {
38+
mut s := Stack[int]{}
39+
_, ok := s.Peek()
40+
t.Assert(!ok, "peek on empty stack should report ok == false")
41+
42+
s.Push(42)
43+
v, ok2 := s.Peek()
44+
t.Assert(ok2 && v == 42, "peek should return the top item (42)")
45+
t.Assert(s.Len() == 1, "peek should not remove the item")
46+
}
47+
48+
#test
49+
fn testStackGenericString(t: &testing::T) {
50+
mut s := Stack[string]{}
51+
s.Push("a")
52+
s.Push("b")
53+
v, ok := s.Pop()
54+
t.Assert(ok && v == "b", "generic string stack should pop \"b\"")
55+
}

0 commit comments

Comments
 (0)