stack_assembly/
stack.rs

1use crate::{Effect, Value};
2
3/// # The operand stack
4///
5/// StackAssembly's evaluation model is based on an implicit stack which
6/// stores all operands.
7///
8/// Aside from this, the stack is an important communication channel between
9/// script and host. Please refer to [`Eval`]'s [`stack`] field for more
10/// information on that.
11///
12/// [`Eval`]: crate::Eval
13/// [`stack`]: struct.Eval.html#structfield.stack
14#[derive(Debug)]
15pub struct Stack {
16    /// # The values on the stack
17    pub values: Vec<Value>,
18}
19
20impl Stack {
21    /// # Push a value to top of the stack
22    pub fn push(&mut self, value: impl Into<Value>) {
23        self.values.push(value.into());
24    }
25
26    /// # Pop a value from the top of the stack
27    ///
28    /// Return [`StackUnderflow`], if no value is available on the stack, which
29    /// provides an automatic conversion to [`Effect`].
30    pub fn pop(&mut self) -> Result<Value, StackUnderflow> {
31        self.values.pop().ok_or(StackUnderflow)
32    }
33
34    /// # Access the stack as a slice of `i32` values
35    pub fn to_i32_slice(&self) -> &[i32] {
36        bytemuck::cast_slice(&self.values)
37    }
38
39    /// # Access the stack as a slice of `u32` values
40    pub fn to_u32_slice(&self) -> &[u32] {
41        bytemuck::cast_slice(&self.values)
42    }
43}
44
45/// # Tried to pop a value from an empty stack
46///
47/// See [`Stack::pop`].
48#[derive(Debug)]
49pub struct StackUnderflow;
50
51impl From<StackUnderflow> for Effect {
52    fn from(StackUnderflow: StackUnderflow) -> Self {
53        Effect::StackUnderflow
54    }
55}