aboutsummaryrefslogtreecommitdiff
path: root/src/lisp/eval.rs
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-05-18 06:39:46 +0100
committerAkshay <[email protected]>2021-05-18 06:39:46 +0100
commitf3a941bb63275b0efbaa88c65e7ba762d8b05237 (patch)
tree1f577c2be937e2052e6d8f292ef4df92c052c928 /src/lisp/eval.rs
parentbea80dbfe722c7bb13e19665ddbadea03b8b6293 (diff)
fix `set!` routine
and discover a drawback of borrowck!
Diffstat (limited to 'src/lisp/eval.rs')
-rw-r--r--src/lisp/eval.rs37
1 files changed, 19 insertions, 18 deletions
diff --git a/src/lisp/eval.rs b/src/lisp/eval.rs
index 784cba0..c5e4ed0 100644
--- a/src/lisp/eval.rs
+++ b/src/lisp/eval.rs
@@ -153,14 +153,9 @@ where
153 match args { 153 match args {
154 [LispExpr::Ident(id), expr] => { 154 [LispExpr::Ident(id), expr] => {
155 let value = self.eval(&expr)?; 155 let value = self.eval(&expr)?;
156 let local_env = self.app.lisp_env.last_mut(); 156 let loc = lookup_mut(&mut self.app.lisp_env, id)?;
157 if let Some(env) = local_env { 157 *loc = value;
158 env.insert(id.into(), value) 158 Ok(LispExpr::Unit)
159 .ok_or_else(|| EvalError::UnboundVariable(id.into()).into())
160 } else {
161 error!("Unable to set in global env!");
162 Err(EvalError::BadForm.into())
163 }
164 } 159 }
165 _ => { 160 _ => {
166 error!("Invalid usage of `set!`"); 161 error!("Invalid usage of `set!`");
@@ -334,16 +329,22 @@ pub fn create_lambda(cdr: &[LispExpr]) -> Result<LispExpr, LispError> {
334} 329}
335 330
336pub fn lookup(env_list: &[Environment], key: &str) -> Result<LispExpr, LispError> { 331pub fn lookup(env_list: &[Environment], key: &str) -> Result<LispExpr, LispError> {
337 if env_list.is_empty() { 332 Ok(env_list
338 Err(EvalError::UnboundVariable(key.into()).into()) 333 .iter()
339 } else { 334 .rev()
340 let local_env = env_list.last().unwrap(); 335 .find_map(|local_env| local_env.get(key).cloned())
341 if let Some(val) = local_env.get(key) { 336 .ok_or(EvalError::UnboundVariable(key.into()))?)
342 Ok(val.clone()) 337}
343 } else { 338
344 lookup(&env_list[..env_list.len() - 1], key) 339pub fn lookup_mut<'a, 'b>(
345 } 340 env_list: &'a mut [Environment],
346 } 341 key: &'b str,
342) -> Result<&'a mut LispExpr, LispError> {
343 Ok(env_list
344 .iter_mut()
345 .rev()
346 .find_map(|local_env| local_env.get_mut(key))
347 .ok_or(EvalError::UnboundVariable(key.into()))?)
347} 348}
348 349
349pub fn completions<'a>(env_list: &'a [Environment], prefix: &str) -> Vec<&'a str> { 350pub fn completions<'a>(env_list: &'a [Environment], prefix: &str) -> Vec<&'a str> {