maolang_core/interp/
sf.rs

1//! Stack Frame Implementation
2
3use std::collections::HashMap;
4
5use crate::parser::ast::Literal;
6
7use super::RuntimeError;
8
9/// A runtime's stack
10#[derive(Debug, Clone)]
11pub struct Stack<'a> {
12    /// The stackframes
13    stack: Vec<StackFrame<'a>>,
14}
15
16impl Default for Stack<'_> {
17    fn default() -> Self {
18        Self {
19            stack: vec![StackFrame::default()],
20        }
21    }
22}
23
24impl<'a> Stack<'a> {
25    /// Pushes a new stack frame
26    pub fn push(&mut self) {
27        self.stack.push(StackFrame::default());
28    }
29
30    /// Pops the current stackframe
31    pub fn pop(&mut self) {
32        self.stack.pop();
33    }
34
35    /// Attempts to get a variable from the current context
36    pub fn get(&mut self, name: &str) -> Result<&mut Literal<'a>, RuntimeError> {
37        let len = self.stack.len() - 1;
38        if let Some(val) = self.stack[len].variables.get_mut(name) {
39            Ok(val)
40        } else {
41            Err(RuntimeError(format!(
42                "Variable with name {name} does not exist in this scope"
43            )))
44        }
45    }
46
47    /// Attempts to set a variable in the current context
48    pub fn set(&mut self, name: String, lit: Literal<'a>) {
49        let len = self.stack.len() - 1;
50        self.stack[len].variables.insert(name, lit);
51    }
52}
53
54/// Context for a single stack frame
55#[derive(Debug, Default, Clone)]
56pub struct StackFrame<'a> {
57    /// All local variables to the stack frame
58    pub variables: HashMap<String, Literal<'a>>,
59}