1use crate::error::PsError;
8use crate::object::PsObject;
9
10pub struct Stack {
12 data: Vec<PsObject>,
13 max_size: usize,
14}
15
16impl Stack {
17 pub fn new(max_size: usize) -> Self {
18 Self {
19 data: Vec::with_capacity(max_size.min(256)),
20 max_size,
21 }
22 }
23
24 #[inline]
26 pub fn push(&mut self, obj: PsObject) -> Result<(), PsError> {
27 if self.data.len() >= self.max_size {
28 return Err(PsError::StackOverflow);
29 }
30 self.data.push(obj);
31 Ok(())
32 }
33
34 pub fn insert_at(&mut self, index: usize, obj: PsObject) -> Result<(), PsError> {
39 if self.data.len() >= self.max_size {
40 return Err(PsError::StackOverflow);
41 }
42 self.data.insert(index, obj);
43 Ok(())
44 }
45
46 #[inline]
48 pub fn pop(&mut self) -> Result<PsObject, PsError> {
49 self.data.pop().ok_or(PsError::StackUnderflow)
50 }
51
52 #[inline]
54 pub fn try_pop(&mut self) -> Option<PsObject> {
55 self.data.pop()
56 }
57
58 #[inline]
60 pub fn peek(&self, from_top: usize) -> Result<PsObject, PsError> {
61 if from_top >= self.data.len() {
62 return Err(PsError::StackUnderflow);
63 }
64 Ok(self.data[self.data.len() - 1 - from_top])
65 }
66
67 pub fn peek_mut(&mut self, from_top: usize) -> Result<&mut PsObject, PsError> {
69 let len = self.data.len();
70 if from_top >= len {
71 return Err(PsError::StackUnderflow);
72 }
73 Ok(&mut self.data[len - 1 - from_top])
74 }
75
76 #[inline]
77 pub fn len(&self) -> usize {
78 self.data.len()
79 }
80
81 #[inline]
82 pub fn is_empty(&self) -> bool {
83 self.data.is_empty()
84 }
85
86 pub fn clear(&mut self) {
87 self.data.clear();
88 }
89
90 pub fn set_max_size(&mut self, max_size: usize) {
92 self.max_size = max_size;
93 }
94
95 pub fn as_slice(&self) -> &[PsObject] {
96 &self.data
97 }
98
99 pub fn as_mut_slice(&mut self) -> &mut [PsObject] {
100 &mut self.data
101 }
102
103 pub fn truncate(&mut self, len: usize) {
104 self.data.truncate(len);
105 }
106
107 pub fn swap_top_two(&mut self) -> Result<(), PsError> {
109 let len = self.data.len();
110 if len < 2 {
111 return Err(PsError::StackUnderflow);
112 }
113 self.data.swap(len - 1, len - 2);
114 Ok(())
115 }
116
117 pub fn max_size(&self) -> usize {
119 self.max_size
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_push_pop() {
129 let mut s = Stack::new(10);
130 s.push(PsObject::int(1)).unwrap();
131 s.push(PsObject::int(2)).unwrap();
132 assert_eq!(s.len(), 2);
133 assert_eq!(s.pop().unwrap().as_i32(), Some(2));
134 assert_eq!(s.pop().unwrap().as_i32(), Some(1));
135 assert!(s.is_empty());
136 }
137
138 #[test]
139 fn test_overflow() {
140 let mut s = Stack::new(2);
141 s.push(PsObject::int(1)).unwrap();
142 s.push(PsObject::int(2)).unwrap();
143 assert_eq!(s.push(PsObject::int(3)), Err(PsError::StackOverflow));
144 }
145
146 #[test]
147 fn test_underflow() {
148 let mut s = Stack::new(10);
149 assert_eq!(s.pop(), Err(PsError::StackUnderflow));
150 }
151
152 #[test]
153 fn test_peek() {
154 let mut s = Stack::new(10);
155 s.push(PsObject::int(10)).unwrap();
156 s.push(PsObject::int(20)).unwrap();
157 s.push(PsObject::int(30)).unwrap();
158 assert_eq!(s.peek(0).unwrap().as_i32(), Some(30));
159 assert_eq!(s.peek(1).unwrap().as_i32(), Some(20));
160 assert_eq!(s.peek(2).unwrap().as_i32(), Some(10));
161 assert_eq!(s.peek(3), Err(PsError::StackUnderflow));
162 }
163
164 #[test]
165 fn test_swap_top_two() {
166 let mut s = Stack::new(10);
167 s.push(PsObject::int(1)).unwrap();
168 s.push(PsObject::int(2)).unwrap();
169 s.swap_top_two().unwrap();
170 assert_eq!(s.peek(0).unwrap().as_i32(), Some(1));
171 assert_eq!(s.peek(1).unwrap().as_i32(), Some(2));
172 }
173}