diff options
author | Akshay <[email protected]> | 2021-05-08 16:55:47 +0100 |
---|---|---|
committer | Akshay <[email protected]> | 2021-05-08 16:55:47 +0100 |
commit | 591d2b6167af53ce07b060711a4074f1e19c5f3f (patch) | |
tree | 6299e12574732b063aa57c977104eacf938e4eda /src/lisp | |
parent | 225351e7c98e91451e0b02fd2b9c3060ebd153a7 (diff) |
add basic user-definable keybinds
Diffstat (limited to 'src/lisp')
-rw-r--r-- | src/lisp/error.rs | 13 | ||||
-rw-r--r-- | src/lisp/eval.rs | 20 | ||||
-rw-r--r-- | src/lisp/std.lisp | 15 |
3 files changed, 43 insertions, 5 deletions
diff --git a/src/lisp/error.rs b/src/lisp/error.rs index 9e9dc90..7bde872 100644 --- a/src/lisp/error.rs +++ b/src/lisp/error.rs | |||
@@ -1,7 +1,10 @@ | |||
1 | use crate::lisp::{ | 1 | use crate::{ |
2 | expr::{Arity, LispExpr}, | 2 | keybind::KeybindError, |
3 | lex::{Span, SpanDisplay}, | 3 | lisp::{ |
4 | number::LispNumber, | 4 | expr::{Arity, LispExpr}, |
5 | lex::{Span, SpanDisplay}, | ||
6 | number::LispNumber, | ||
7 | }, | ||
5 | }; | 8 | }; |
6 | 9 | ||
7 | use std::{fmt, io}; | 10 | use std::{fmt, io}; |
@@ -104,6 +107,7 @@ pub enum EvalError { | |||
104 | AssertionError { expected: LispExpr, got: LispExpr }, | 107 | AssertionError { expected: LispExpr, got: LispExpr }, |
105 | ScriptLoadError(io::Error), | 108 | ScriptLoadError(io::Error), |
106 | CustomInternal(&'static str), | 109 | CustomInternal(&'static str), |
110 | KeybindError(KeybindError), | ||
107 | Custom(String), | 111 | Custom(String), |
108 | } | 112 | } |
109 | 113 | ||
@@ -134,6 +138,7 @@ impl fmt::Display for EvalError { | |||
134 | write!(f, "assertion error: expected `{}` got `{}`", expected, got) | 138 | write!(f, "assertion error: expected `{}` got `{}`", expected, got) |
135 | } | 139 | } |
136 | Self::ScriptLoadError(s) => write!(f, "error while loading script: {}", s), | 140 | Self::ScriptLoadError(s) => write!(f, "error while loading script: {}", s), |
141 | Self::KeybindError(k) => write!(f, "keybind error: {}", k), | ||
137 | Self::CustomInternal(s) => write!(f, "{}", s), | 142 | Self::CustomInternal(s) => write!(f, "{}", s), |
138 | Self::Custom(s) => write!(f, "error: {}", s), | 143 | Self::Custom(s) => write!(f, "error: {}", s), |
139 | } | 144 | } |
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 @@ | |||
1 | use crate::{ | 1 | use 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 | ||
11 | use std::convert::TryInto; | 12 | use std::{convert::TryInto, str::FromStr}; |
12 | 13 | ||
13 | use log::{error, info}; | 14 | use 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 | ||
307 | pub fn apply_quote(arg: &LispExpr) -> LispExpr { | 325 | pub fn apply_quote(arg: &LispExpr) -> LispExpr { |
diff --git a/src/lisp/std.lisp b/src/lisp/std.lisp index a256125..fe09a8a 100644 --- a/src/lisp/std.lisp +++ b/src/lisp/std.lisp | |||
@@ -72,3 +72,18 @@ | |||
72 | acc | 72 | acc |
73 | (rev-helper (cdr p) (cons (car p) acc)))) | 73 | (rev-helper (cdr p) (cons (car p) acc)))) |
74 | (rev-helper ls '()))) | 74 | (rev-helper ls '()))) |
75 | |||
76 | (define (append l1 l2) | ||
77 | (if (null? l1) | ||
78 | l2 | ||
79 | (cons (car l1) | ||
80 | (append (cdr l1) l2)))) | ||
81 | |||
82 | (define (cross xs ys) | ||
83 | (if (or (null? xs) | ||
84 | (null? ys)) | ||
85 | '() | ||
86 | (fold '() | ||
87 | append | ||
88 | (map (lambda (x) | ||
89 | (map (lambda (y) (list x y)) ys)) xs)))) | ||