aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-03-31 13:46:18 +0100
committerAkshay <[email protected]>2021-03-31 13:46:18 +0100
commitb69d30225f77653dc89652a9ba838d2e9fba4948 (patch)
tree588bc93d4a24dde15513876724fc75f0ba2c895d
parent5d541cb5c87ffb80262c753394f06f4449609b9b (diff)
hopefully fix quote for the last time
-rw-r--r--src/lisp/eval.rs37
-rw-r--r--src/lisp/std.lisp7
2 files changed, 31 insertions, 13 deletions
diff --git a/src/lisp/eval.rs b/src/lisp/eval.rs
index cb8ce68..d11ad30 100644
--- a/src/lisp/eval.rs
+++ b/src/lisp/eval.rs
@@ -31,7 +31,7 @@ where
31 LispExpr::Number(_) => Ok(expr.clone()), 31 LispExpr::Number(_) => Ok(expr.clone()),
32 LispExpr::BoolLit(_) => Ok(expr.clone()), 32 LispExpr::BoolLit(_) => Ok(expr.clone()),
33 LispExpr::Ident(ref id) => lookup(&self.app.lisp_env, id), 33 LispExpr::Ident(ref id) => lookup(&self.app.lisp_env, id),
34 LispExpr::Quote(_, _) => Ok(expr.clone()), 34 LispExpr::Quote(item, _) => Ok(apply_quote(&item.as_ref())),
35 LispExpr::List(li) => { 35 LispExpr::List(li) => {
36 let func_expr = &li[0]; 36 let func_expr = &li[0];
37 match func_expr { 37 match func_expr {
@@ -41,7 +41,7 @@ where
41 "lambda" => create_lambda(&li[1..]), 41 "lambda" => create_lambda(&li[1..]),
42 "if" => self.eval_if(&li[1..]), 42 "if" => self.eval_if(&li[1..]),
43 "cond" => self.eval_cond(&li[1..]), 43 "cond" => self.eval_cond(&li[1..]),
44 "quote" => quote_var(&li[1..]), 44 "quote" => Ok(apply_quote(&li[1])),
45 _ => { 45 _ => {
46 let mut new_ls = vec![self.eval(&func_expr)?]; 46 let mut new_ls = vec![self.eval(&func_expr)?];
47 new_ls.extend(li[1..].to_vec()); 47 new_ls.extend(li[1..].to_vec());
@@ -215,12 +215,15 @@ where
215 } 215 }
216} 216}
217 217
218pub fn quote_var(args: &[LispExpr]) -> Result<LispExpr, LispError> { 218pub fn apply_quote(arg: &LispExpr) -> LispExpr {
219 let arity = Arity::Exact(1); 219 match arg {
220 if !arity.check(args) { 220 i @ LispExpr::Unit
221 return Err(arity.to_error()); 221 | i @ LispExpr::StringLit(_)
222 } else { 222 | i @ LispExpr::Char(_)
223 return Ok(args[0].clone().quote(1)); 223 | i @ LispExpr::Number(_)
224 | i @ LispExpr::BoolLit(_) => i.clone(),
225 LispExpr::List(ls) => LispExpr::List(ls.iter().map(|a| apply_quote(a)).collect::<Vec<_>>()),
226 _ => arg.clone(),
224 } 227 }
225} 228}
226 229
@@ -313,12 +316,28 @@ mod tests {
313 assert!(run("(eq? '(1 2 3) '(1 2 3))", app).cast_bool()); 316 assert!(run("(eq? '(1 2 3) '(1 2 3))", app).cast_bool());
314 assert!(run("(eq? '(1 '(1 2 3)) '(1 '(1 2 3)))", app).cast_bool(),); 317 assert!(run("(eq? '(1 '(1 2 3)) '(1 '(1 2 3)))", app).cast_bool(),);
315 assert!(run("(eq? '#t '#t)", app).cast_bool()); 318 assert!(run("(eq? '#t '#t)", app).cast_bool());
319
320 assert!(run("(eq? 1 '1)", app).cast_bool());
321 assert_eq!(
322 run("'(1 2 3)", app),
323 LispExpr::List(
324 vec![1, 2, 3]
325 .into_iter()
326 .map(LispNumber::Integer)
327 .map(LispExpr::Number)
328 .collect()
329 ),
330 );
331 assert_eq!(
332 run("(caar (cdr '(1 (4 5))))", app),
333 LispExpr::Number(LispNumber::Integer(4))
334 );
316 } 335 }
317 336
318 fn eval_logical(app: &mut AppState) { 337 fn eval_logical(app: &mut AppState) {
319 assert!(run("(and #t #t)", app).cast_bool()); 338 assert!(run("(and #t #t)", app).cast_bool());
320 assert!(run("(or #f #t)", app).cast_bool()); 339 assert!(run("(or #f #t)", app).cast_bool());
321 assert!(run("(not #t)", app).cast_bool()); 340 assert!(!run("(not #t)", app).cast_bool());
322 assert_eq!(run("(not #f)", app), run("(not (not #t))", app)); 341 assert_eq!(run("(not #f)", app), run("(not (not #t))", app));
323 } 342 }
324} 343}
diff --git a/src/lisp/std.lisp b/src/lisp/std.lisp
index 8350482..d54b32c 100644
--- a/src/lisp/std.lisp
+++ b/src/lisp/std.lisp
@@ -36,10 +36,9 @@
36 (filter pred (cdr ls))))) 36 (filter pred (cdr ls)))))
37 37
38(define (member? item ls) 38(define (member? item ls)
39 (if (null? ls) 39 (fold #f
40 #f 40 (lambda (acc x) (or acc (eq? item x)))
41 (or (eq? item (car ls)) 41 ls))
42 (member? item (cdr ls)))))
43 42
44(define (assert expr) 43(define (assert expr)
45 (assert-eq #t expr)) 44 (assert-eq #t expr))