1use crate::value::Value;
6use std::cell::RefCell;
7use std::collections::HashMap;
8use std::rc::Rc;
9
10pub struct EnvironmentPool {
12 pool: Vec<Environment>,
14 max_size: usize,
16}
17
18impl EnvironmentPool {
19 pub fn new() -> Self {
21 Self::with_capacity(50)
22 }
23
24 pub fn with_capacity(max_size: usize) -> Self {
26 EnvironmentPool {
27 pool: Vec::with_capacity(max_size.min(50)),
28 max_size,
29 }
30 }
31
32 pub fn acquire(&mut self) -> Environment {
34 self.pool.pop().unwrap_or_default()
35 }
36
37 pub fn release(&mut self, mut env: Environment) {
39 if self.pool.len() < self.max_size {
40 env.clear();
41 env.parent = None;
42 self.pool.push(env);
43 }
44 }
45
46 pub fn clear(&mut self) {
48 self.pool.clear();
49 }
50}
51
52impl Default for EnvironmentPool {
53 fn default() -> Self {
54 Self::new()
55 }
56}
57
58#[derive(Debug, Clone)]
60pub struct Environment {
61 store: HashMap<String, Value>,
63
64 parent: Option<Rc<RefCell<Environment>>>,
66}
67
68impl Environment {
69 pub fn new() -> Self {
71 Environment {
72 store: HashMap::with_capacity(16), parent: None,
74 }
75 }
76
77 pub fn with_parent(parent: Rc<RefCell<Environment>>) -> Self {
79 Environment {
80 store: HashMap::with_capacity(8), parent: Some(parent),
82 }
83 }
84
85 pub fn set(&mut self, name: String, value: Value) {
87 self.store.insert(name, value);
88 }
89
90 pub fn get(&self, name: &str) -> Option<Value> {
92 if let Some(value) = self.store.get(name) {
94 return Some(value.clone());
95 }
96
97 self.get_from_parent(name)
99 }
100
101 #[inline(never)]
103 fn get_from_parent(&self, name: &str) -> Option<Value> {
104 self.parent.as_ref()?.borrow().get(name)
105 }
106
107 pub fn has(&self, name: &str) -> bool {
109 self.store.contains_key(name) || self.parent.as_ref().is_some_and(|p| p.borrow().has(name))
110 }
111
112 pub fn update(&mut self, name: &str, value: Value) -> bool {
115 if self.store.contains_key(name) {
116 self.store.insert(name.to_string(), value);
117 return true;
118 }
119
120 if let Some(parent) = &self.parent {
121 return parent.borrow_mut().update(name, value);
122 }
123
124 false
125 }
126
127 pub fn keys(&self) -> Vec<String> {
129 self.store.keys().cloned().collect()
130 }
131
132 pub fn clear(&mut self) {
134 self.store.clear();
135 }
136}
137
138impl Default for Environment {
139 fn default() -> Self {
140 Self::new()
141 }
142}
143
144#[cfg(test)]
145mod tests {
146 use super::*;
147
148 #[test]
149 fn test_environment_set_get() {
150 let mut env = Environment::new();
151 env.set("x".to_string(), Value::Number(42.0));
152
153 assert_eq!(env.get("x"), Some(Value::Number(42.0)));
154 assert_eq!(env.get("y"), None);
155 }
156
157 #[test]
158 fn test_environment_has() {
159 let mut env = Environment::new();
160 env.set("x".to_string(), Value::Number(42.0));
161
162 assert!(env.has("x"));
163 assert!(!env.has("y"));
164 }
165
166 #[test]
167 fn test_environment_update() {
168 let mut env = Environment::new();
169 env.set("x".to_string(), Value::Number(42.0));
170
171 assert!(env.update("x", Value::Number(100.0)));
172 assert_eq!(env.get("x"), Some(Value::Number(100.0)));
173
174 assert!(!env.update("y", Value::Number(200.0)));
175 }
176
177 #[test]
178 fn test_environment_parent_scope() {
179 let parent = Rc::new(RefCell::new(Environment::new()));
180 parent
181 .borrow_mut()
182 .set("x".to_string(), Value::Number(42.0));
183
184 let mut child = Environment::with_parent(parent.clone());
185 child.set("y".to_string(), Value::Number(100.0));
186
187 assert_eq!(child.get("x"), Some(Value::Number(42.0)));
189 assert_eq!(child.get("y"), Some(Value::Number(100.0)));
190
191 assert_eq!(parent.borrow().get("x"), Some(Value::Number(42.0)));
193 assert_eq!(parent.borrow().get("y"), None);
194 }
195
196 #[test]
197 fn test_environment_shadowing() {
198 let parent = Rc::new(RefCell::new(Environment::new()));
199 parent
200 .borrow_mut()
201 .set("x".to_string(), Value::Number(42.0));
202
203 let mut child = Environment::with_parent(parent.clone());
204 child.set("x".to_string(), Value::Number(100.0));
205
206 assert_eq!(child.get("x"), Some(Value::Number(100.0)));
208 assert_eq!(parent.borrow().get("x"), Some(Value::Number(42.0)));
209 }
210
211 #[test]
212 fn test_environment_update_in_parent() {
213 let parent = Rc::new(RefCell::new(Environment::new()));
214 parent
215 .borrow_mut()
216 .set("x".to_string(), Value::Number(42.0));
217
218 let mut child = Environment::with_parent(parent.clone());
219
220 assert!(child.update("x", Value::Number(100.0)));
222 assert_eq!(parent.borrow().get("x"), Some(Value::Number(100.0)));
223 assert_eq!(child.get("x"), Some(Value::Number(100.0)));
224 }
225
226 #[test]
227 fn test_environment_keys() {
228 let mut env = Environment::new();
229 env.set("x".to_string(), Value::Number(42.0));
230 env.set("y".to_string(), Value::String("hello".to_string()));
231
232 let keys = env.keys();
233 assert_eq!(keys.len(), 2);
234 assert!(keys.contains(&"x".to_string()));
235 assert!(keys.contains(&"y".to_string()));
236 }
237
238 #[test]
239 fn test_environment_clear() {
240 let mut env = Environment::new();
241 env.set("x".to_string(), Value::Number(42.0));
242 env.set("y".to_string(), Value::String("hello".to_string()));
243
244 env.clear();
245
246 assert_eq!(env.get("x"), None);
247 assert_eq!(env.get("y"), None);
248 assert_eq!(env.keys().len(), 0);
249 }
250}