use std::{ collections::HashMap, sync::{Arc, RwLock}, }; use crate::value::Value; #[derive(Debug, Clone)] pub struct Env<'env> { values: Arc>>, parent: Option<&'env Env<'env>>, } impl Env<'_> { pub fn new() -> Self { Env { values: Arc::default(), parent: None, } } pub fn get(&self, name: &str) -> Option { if let Some(v) = self.values.read().unwrap().get(name) { Some(v.clone()) } else if let Some(parent) = &self.parent { parent.get(name) } else { None } } pub fn set_here(&self, name: &str, value: Value) { self.values.write().unwrap().insert(name.to_string(), value); } pub fn set(&self, name: &str, value: impl Into) { let value = value.into(); if !self.set_recursive(name, &value) { self.values.write().unwrap().insert(name.to_string(), value); } } fn set_recursive(&self, name: &str, value: &Value) -> bool { if let Some(v) = self.values.write().unwrap().get_mut(name) { *v = value.clone(); true } else if let Some(parent) = self.parent { parent.set_recursive(name, value) } else { false } } } impl Default for Env<'_> { fn default() -> Self { Self::new() } } impl<'env> Env<'env> { pub fn new_with_parent(parent: &'env Env<'env>) -> Self { Env { values: Arc::default(), parent: Some(parent), } } }