1use std::cell::RefCell;
2use std::collections::HashMap;
3use std::rc::Rc;
4use std::sync::Arc;
5use crate::token::Token;
6use crate::Program;
7use crate::Values;
8#[derive(Clone)]
19pub struct Context {
20 pub(crate) tokens: Rc<RefCell<Vec<Rc<RefCell<Box<dyn Token + 'static>>>>>>,
21 pub(crate) functions: Rc<RefCell<HashMap<String, Arc<dyn Fn(Vec<Values>, &mut Program) -> Values>>>>,
22 pub(crate) memory: Rc<RefCell<HashMap<String , Values>>>,
23 pub(crate) keys: Rc<RefCell<HashMap<String, Arc<dyn Fn(String, &mut Program) -> Values>>>>,
24 pub(crate) sub_context: Option<Box<Context>>
25}
26
27impl Context {
28 pub fn new<'b>() -> Context {
30 Context {
31 tokens: Rc::new(RefCell::new(Vec::new())),
32 memory: Rc::new(RefCell::new(HashMap::new())),
33 keys: Rc::new(RefCell::new(HashMap::new())),
34 functions: Rc::new(RefCell::new(HashMap::new())),
35 sub_context: None
36 }
37 }
38 pub fn token_index(&self, tok: &str) -> Option<usize> {
43 for ix in 0..self.tokens.borrow().len() {
44 let def_tok = &self.tokens.borrow()[ix];
45 if def_tok.borrow().is_token(&tok) { return Some(ix); }
46 }
47 None
48 }
49 pub fn push_token(&mut self, tok: Box<dyn Token>) {
51 self.tokens.borrow_mut().push(Rc::new(RefCell::new(tok)));
52 }
53 pub fn push_memory(&mut self, key: &str, tok: Values) {
55 if !self.memory.borrow().contains_key(key) {
56 if let Some(subc) = &mut self.sub_context {
57 subc.push_memory(key, tok);
58 return;
59 }
60 }
61 self.memory.borrow_mut().insert(key.to_owned(),tok);
62 }
63 pub fn push_key(&mut self, key: String, tok: impl Fn(String, &mut Program) -> Values + 'static) {
65 self.keys.borrow_mut().insert(key, Arc::new(tok));
66 }
67 pub fn push_function(&mut self, name: String, func: impl Fn(Vec<Values>, &mut Program) -> Values + 'static) {
69 if let Some(subc) = &mut self.sub_context {
70 if !self.functions.borrow().contains_key(&name) {
71 subc.push_function(name, func);
72 return;
73 }
74 }
75 self.functions.borrow_mut().insert(name, Arc::new(func));
76 }
77 pub fn get_token(&self, idx: usize) -> Rc<RefCell<Box<dyn Token + 'static>>> {
78 self.tokens.borrow().get(idx).unwrap().clone()
79 }
80 pub fn get_memory(&self, key: &str) -> Values {
81 if !self.memory.borrow().contains_key(key) {
82 if let Some(subc) = &self.sub_context {
83 if subc.memory.borrow().contains_key(key) {
84 return subc.get_memory(key);
85 } else {
86 panic!("Memory \"{}\" no longer exists", key);
87 }
88 } else {
89 panic!("Memory {} not pushed", key);
90 }
91 }
92 self.memory.borrow().get(key).unwrap().clone()
93 }
94 pub fn get_key(&self, key: &str) -> Arc<dyn Fn(String, &mut Program) -> Values> {
95 self.keys.borrow().get(key).unwrap().clone()
96 }
97 pub fn get_function(&self, key: &str) -> Arc<dyn Fn(Vec<Values>, &mut Program) -> Values> {
98 if !self.functions.borrow().contains_key(key) {
99 if let Some(subc) = &self.sub_context {
100 if subc.functions.borrow().contains_key(key) {
101 return subc.get_function(key);
102 } else {
103 panic!("Function \"{}\" no longer exists", key);
104 }
105 } else {
106 panic!("Function {} not pushed", key);
107 }
108 }
109 self.functions.borrow().get(key).unwrap().clone()
110 }
111
112
113 pub fn has_token(&self, idx: usize) -> bool {
114 self.tokens.borrow().len() > idx
115 }
116 pub fn has_memory(&self, key: &str) -> bool {
117 let has_sub_context = {
118 if let Some(subc) = &self.sub_context {
119 subc.has_memory(key)
120 } else {
121 false
122 }
123 };
124 self.memory.borrow().contains_key(key) || has_sub_context
125 }
126 pub fn has_key(&self, key: &str) -> bool {
127 self.keys.borrow().contains_key(key)
128 }
129 pub fn has_function(&self, key: &str) -> bool {
130 let has_sub_context = {
131 if let Some(subc) = &self.sub_context {
132 subc.has_function(key)
133 } else {
134 false
135 }
136 };
137 self.functions.borrow().contains_key(key) || has_sub_context
138 }
139
140 pub fn gifs_token(&self, idx: usize) -> Option<Rc<RefCell<Box<dyn Token + 'static>>>> {
141 if self.has_token(idx) {
142 Some(self.get_token(idx))
143 } else { None }
144 }
145 pub fn gifs_memory(&self, key: &str) -> Option<Values> {
146 if self.has_memory(key) {
147 Some(self.get_memory(key))
148 } else { None }
149 }
150 pub fn gifs_key(&self, key: &str) -> Option<Arc<dyn Fn(String, &mut Program) -> Values>> {
151 if self.has_memory(key) {
152 Some(self.get_key(key))
153 } else { None }
154 }
155 pub fn gifs_function(&self, key: &str) -> Option<Arc<dyn Fn(String, &mut Program) -> Values>> {
156 if self.has_memory(key) {
157 Some(self.get_key(key))
158 } else { None }
159 }
160}