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
10impl 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}