aboutsummaryrefslogtreecommitdiff
path: root/src/lisp/eval.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lisp/eval.rs')
-rw-r--r--src/lisp/eval.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/lisp/eval.rs b/src/lisp/eval.rs
index 75cb5c9..677fa23 100644
--- a/src/lisp/eval.rs
+++ b/src/lisp/eval.rs
@@ -1,5 +1,6 @@
1use crate::{ 1use crate::{
2 app::AppState, 2 app::AppState,
3 keybind::Keybind,
3 lisp::{ 4 lisp::{
4 error::{EvalError, LispError}, 5 error::{EvalError, LispError},
5 expr::{Arity, Ident, LispExpr, LispFunction}, 6 expr::{Arity, Ident, LispExpr, LispFunction},
@@ -8,7 +9,7 @@ use crate::{
8 type_match, 9 type_match,
9}; 10};
10 11
11use std::convert::TryInto; 12use std::{convert::TryInto, str::FromStr};
12 13
13use log::{error, info}; 14use log::{error, info};
14 15
@@ -44,6 +45,7 @@ where
44 "for" => self.eval_for(&li[1..]), 45 "for" => self.eval_for(&li[1..]),
45 "quote" => Ok(apply_quote(&li[1])), 46 "quote" => Ok(apply_quote(&li[1])),
46 "let" => self.eval_let(&li[1..]), 47 "let" => self.eval_let(&li[1..]),
48 "bind-key" => self.eval_bind_key(&li[1..]),
47 _ => { 49 _ => {
48 let mut new_ls = vec![self.eval(&func_expr)?]; 50 let mut new_ls = vec![self.eval(&func_expr)?];
49 new_ls.extend(li[1..].to_vec()); 51 new_ls.extend(li[1..].to_vec());
@@ -302,6 +304,22 @@ where
302 } 304 }
303 } 305 }
304 } 306 }
307
308 pub fn eval_bind_key(&mut self, args: &[LispExpr]) -> Result<LispExpr, LispError> {
309 let arity = Arity::Exact(2);
310 if !arity.check(args) {
311 Err(arity.to_error())
312 } else {
313 match args {
314 [LispExpr::StringLit(s), body] => {
315 let bind = Keybind::from_str(&s).map_err(EvalError::KeybindError)?;
316 self.app.keybinds.insert(bind, body.clone());
317 Ok(LispExpr::Unit)
318 }
319 _ => Err(EvalError::BadForm.into()),
320 }
321 }
322 }
305} 323}
306 324
307pub fn apply_quote(arg: &LispExpr) -> LispExpr { 325pub fn apply_quote(arg: &LispExpr) -> LispExpr {