bexeval/
context.rs

1use std::collections::HashMap;
2use crate::parser::{Parser, ParserError};
3use crate::value_type::Integer;
4
5pub struct Context<T: Integer = i32> {
6    parser: Parser<T>,
7    var_info: HashMap<String, T>
8}
9
10/// By default, `i32` is used as the value type
11impl Default for Context {
12    fn default() -> Self {
13        Context::<i32>::new()
14    }
15}
16
17impl<T: Integer> Context<T> {
18    pub fn new() -> Self {
19        Self {
20            parser: Parser::<T>::new(),
21            var_info: HashMap::new()
22        }
23    }
24
25    pub fn assign(&mut self, var: &str, val: T) {
26        self.var_info.insert(var.to_string(), val);
27    }
28
29    pub fn assign_stmt(&mut self, stmt: &str) -> Result<(), ParserError> {
30        let (var, val) = self.parser.parse_statement(stmt, &self.var_info)?;
31        self.assign(&var, val);
32        Ok(())
33    }
34
35    pub fn eval(&self, src: &str) -> Result<T, ParserError> {
36        self.parser.eval_inner(src, &self.var_info)
37    }
38
39    pub fn clear(&mut self) {
40        self.var_info.clear();
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn test_context() {
50        let mut ctx = Context::<i32>::new();
51        ctx.assign("x", 1);
52        assert_eq!(ctx.eval("x + 3").unwrap(), 4);
53        ctx.assign_stmt("y = x + 5").unwrap();
54        assert_eq!(ctx.eval("y + x * 2").unwrap(), 8);
55    }
56}