use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;
use crate::token::Token;
use crate::program::ProgramBlock;
use crate::values::Values;
pub struct Context {
pub(crate) tokens: Vec<Rc<RefCell<Box<dyn Token + 'static>>>>,
pub(crate) functions: HashMap<String, Arc<dyn Fn(String, &mut ProgramBlock) -> Values>>,
pub(crate) memory: HashMap<String , Values>,
pub(crate) keys: HashMap<String, Arc<dyn Fn(String, &mut ProgramBlock) -> Values>>
}
impl Context {
pub fn new<'b>() -> Context {
Context {
tokens: Vec::new(),
memory: HashMap::new(),
keys: HashMap::new(),
functions: HashMap::new()
}
}
pub fn token_index(&self, tok: &str) -> usize {
for ix in 0..self.tokens.len() {
let def_tok = &self.tokens[ix];
if def_tok.borrow().is_token(&tok) { return ix; }
}
panic!("Token \"{}\" no registered", tok);
}
pub fn push_token(&mut self, tok: Box<dyn Token>) {
self.tokens.push(Rc::new(RefCell::new(tok)));
}
pub fn push_memory(&mut self, key: &str, tok: Values) {
self.memory.insert(key.to_owned(),tok);
}
pub fn push_key(&mut self, key: String, tok: impl Fn(String, &mut ProgramBlock) -> Values + 'static) {
self.keys.insert(key, Arc::new(tok));
}
pub fn push_function(&mut self, name: String, func: impl Fn(String, &mut ProgramBlock) -> Values + 'static) {
self.functions.insert(name, Arc::new(func));
}
pub(crate) fn get_token(&self, idx: usize) -> Rc<RefCell<Box<dyn Token + 'static>>> {
self.tokens.get(idx).unwrap().clone()
}
}