1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//! A call frame.
//!
//! Used internally by the `Machine` to keep track of call scope.

use write_many_table::WriteManyTable;
use table::Table;

/// A call frame.
///
/// Contains:
/// * A `WriteManyTable` for storage of local variables.
/// * A return address - the instruction pointer for the machine to return to
///   when returning from this call.
#[derive(Debug)]
pub struct Frame<T> {
    locals: WriteManyTable<T>,
    pub return_address: usize
}

impl<T> Frame<T> {
    /// Creates a new call frame with the specified return address.
    pub fn new(return_address: usize) -> Frame<T> {
        Frame {
            locals: WriteManyTable::new(),
            return_address: return_address
        }
    }

    /// Return a reference to the specified local variable.
    pub fn get_local(&self, name: &str) -> Option<&T> {
        self.locals.get(name)
    }

    /// Set the value of a local variable.
    pub fn set_local(&mut self, name: &str, value: T) {
        self.locals.insert(name, value);
    }
}

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

    #[test]
    fn new_has_locals() {
        let frame: Frame<usize> = Frame::new(0);
        assert!(frame.locals.is_empty())
    }
}