1use std::{
2 borrow::Borrow,
3 collections::HashMap,
4 hash::Hash,
5 ops::{Index, IndexMut},
6 rc::Rc,
7};
8
9pub type Env<K, V> = Box<HashMap<K, V>>;
11
12#[derive(Debug)]
26pub enum LexicalScope<K, V> {
27 Empty,
29 Root(Env<K, V>),
31 Nested(Rc<LexicalScope<K, V>>, Env<K, V>),
34}
35impl<K, V> Clone for LexicalScope<K, V>
36where
37 K: Clone,
38 V: Clone,
39{
40 fn clone(&self) -> Self {
41 match self {
42 Self::Empty => Self::Empty,
43 Self::Root(scope) => Self::Root(scope.clone()),
44 Self::Nested(parent, scope) => Self::Nested(Rc::clone(parent), scope.clone()),
45 }
46 }
47}
48impl<K, V> Default for LexicalScope<K, V> {
49 fn default() -> Self {
50 Self::Empty
51 }
52}
53impl<K, V> LexicalScope<K, V> {
54 pub fn is_empty(&self) -> bool {
56 match self {
57 Self::Empty => true,
58 Self::Root(_) => false,
59 Self::Nested(parent, env) => env.is_empty() && parent.is_empty(),
60 }
61 }
62}
63
64impl<K, V> LexicalScope<K, V>
65where
66 K: Clone,
67 V: Clone,
68{
69 pub fn enter(&mut self) {
72 let moved = Rc::new(core::mem::take(self));
73 *self = Self::Nested(moved, Env::default());
74 }
75
76 pub fn exit(&mut self) {
78 match core::mem::replace(self, Self::Empty) {
79 Self::Empty | Self::Root(_) => (),
80 Self::Nested(parent, _) => {
81 *self = Rc::unwrap_or_clone(parent);
82 }
83 }
84 }
85}
86impl<K, V> LexicalScope<K, V>
87where
88 K: Eq + Hash,
89{
90 pub fn insert(&mut self, k: K, v: V) -> Option<V> {
96 match self {
97 Self::Empty => {
98 let mut env = Env::default();
99 env.insert(k, v);
100 *self = Self::Root(env);
101 None
102 }
103 Self::Root(env) => env.insert(k, v),
104 Self::Nested(_, env) => env.insert(k, v),
105 }
106 }
107
108 pub fn get<Q>(&self, key: &Q) -> Option<&V>
109 where
110 K: Borrow<Q>,
111 Q: Eq + Hash + ?Sized,
112 {
113 match self {
114 Self::Empty => None,
115 Self::Root(env) => env.get(key),
116 Self::Nested(parent, env) => env.get(key).or_else(|| parent.get(key)),
117 }
118 }
119
120 pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
121 where
122 K: Borrow<Q>,
123 Q: Eq + Hash + ?Sized,
124 {
125 match self {
126 Self::Empty => None,
127 Self::Root(env) => env.get_mut(key),
128 Self::Nested(parent, env) => env
129 .get_mut(key)
130 .or_else(|| Rc::get_mut(parent).and_then(|p| p.get_mut(key))),
131 }
132 }
133
134 pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
135 where
136 K: Borrow<Q>,
137 Q: Eq + Hash + ?Sized,
138 {
139 match self {
140 Self::Empty => None,
141 Self::Root(env) => env.get_key_value(key),
142 Self::Nested(parent, env) => {
143 env.get_key_value(key).or_else(|| parent.get_key_value(key))
144 }
145 }
146 }
147
148 pub fn get_key<Q>(&self, key: &Q) -> Option<&K>
154 where
155 K: Borrow<Q>,
156 Q: Eq + Hash + ?Sized,
157 {
158 self.get_key_value(key).map(|(k, _)| k)
159 }
160}
161impl<K, V, Q> Index<&Q> for LexicalScope<K, V>
162where
163 K: Eq + Hash + Borrow<Q>,
164 Q: Eq + Hash + ?Sized,
165{
166 type Output = V;
167
168 #[inline]
169 fn index(&self, key: &Q) -> &Self::Output {
170 self.get(key).unwrap()
171 }
172}
173impl<K, V, Q> IndexMut<&Q> for LexicalScope<K, V>
174where
175 K: Eq + Hash + Borrow<Q>,
176 Q: Eq + Hash + ?Sized,
177{
178 #[inline]
179 fn index_mut(&mut self, key: &Q) -> &mut Self::Output {
180 self.get_mut(key).unwrap()
181 }
182}