brainterpreter 0.1.1

An interpreter for a Bauble toy programming language
Documentation
use crate::value::ValueType;
use crate::vm::{VmRuntimeError, VmStack, STACK_SIZE};

impl VmStack {
    pub fn pop(&mut self) -> Result<ValueType, VmRuntimeError> {
        self.stack.pop().ok_or(VmRuntimeError::StackExhausted)
    }

    pub fn get(&self, offset: usize) -> Option<&ValueType> {
        self.stack.get(offset)
    }

    pub fn peek(&self, offset: usize) -> Option<&ValueType> {
        self.stack.get(self.stack.len() - offset - 1)
    }

    pub fn last(&self) -> Option<&ValueType> {
        self.stack.last()
    }

    pub fn len(&self) -> usize {
        self.stack.len()
    }

    pub fn is_empty(&self) -> bool {
        self.stack.is_empty()
    }

    pub fn push(&mut self, value: ValueType) {
        self.stack.push(value);
    }

    pub fn set(&mut self, offset: usize, value: ValueType) -> Result<(), VmRuntimeError> {
        if let Some(v) = self.stack.get_mut(offset) {
            *v = value;
            Ok(())
        } else {
            Err(VmRuntimeError::StackExhausted)
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn set_value_by_offset() {
        let mut stack = VmStack::default();
        stack.push(ValueType::Number(1.0));
        stack.push(ValueType::Number(2.0));
        stack.set(0, ValueType::Number(3.0)).unwrap();
        stack.set(1, ValueType::Number(4.0)).unwrap();
        assert_eq!(stack.stack[0], ValueType::Number(3.0));
        assert_eq!(stack.stack[1], ValueType::Number(4.0));
    }
}

impl Default for VmStack {
    fn default() -> Self {
        let stack = Vec::with_capacity(STACK_SIZE);
        VmStack { stack }
    }
}