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
50
51
52
53
54
use ast::NumericLiteral;
use constants::CustomFn;
use std::{collections::HashMap, convert::Into};

pub enum Variable {
    Number(NumericLiteral),
    Function(CustomFn),
}

// Allows users to just pass in integers, not whatever type is used internally
macro_rules! num_into_var {
    ($($ty:ty)*) => {
        $(impl From<$ty> for Variable {
            fn from(val: $ty) -> Variable {
                Variable::Number(val as NumericLiteral)
            }
        })*
    }
}

num_into_var!(i8 i16 i32 i64 u8 u16 u32 u64 isize usize f32);

impl From<CustomFn> for Variable {
    fn from(val: CustomFn) -> Variable {
        Variable::Function(val)
    }
}

pub struct Scope {
    variables: HashMap<String, Variable>,
}

impl Scope {
    pub fn new() -> Self {
        Scope {
            variables: HashMap::new(),
        }
    }

    pub fn with_capacity(cap: usize) -> Self {
        Scope {
            variables: HashMap::with_capacity(cap),
        }
    }

    pub fn set_var<T: Into<Variable>>(&mut self, var_name: &str, value: T) {
        self.variables
            .insert(var_name.to_string(), value.into());
    }

    pub fn get_var(&self, var_name: &str) -> Option<&Variable> {
        self.variables.get(var_name)
    }
}