From b69d30225f77653dc89652a9ba838d2e9fba4948 Mon Sep 17 00:00:00 2001 From: Akshay Date: Wed, 31 Mar 2021 18:16:18 +0530 Subject: hopefully fix quote for the last time --- src/lisp/eval.rs | 37 ++++++++++++++++++++++++++++--------- src/lisp/std.lisp | 7 +++---- 2 files changed, 31 insertions(+), 13 deletions(-) (limited to 'src/lisp') 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 LispExpr::Number(_) => Ok(expr.clone()), LispExpr::BoolLit(_) => Ok(expr.clone()), LispExpr::Ident(ref id) => lookup(&self.app.lisp_env, id), - LispExpr::Quote(_, _) => Ok(expr.clone()), + LispExpr::Quote(item, _) => Ok(apply_quote(&item.as_ref())), LispExpr::List(li) => { let func_expr = &li[0]; match func_expr { @@ -41,7 +41,7 @@ where "lambda" => create_lambda(&li[1..]), "if" => self.eval_if(&li[1..]), "cond" => self.eval_cond(&li[1..]), - "quote" => quote_var(&li[1..]), + "quote" => Ok(apply_quote(&li[1])), _ => { let mut new_ls = vec![self.eval(&func_expr)?]; new_ls.extend(li[1..].to_vec()); @@ -215,12 +215,15 @@ where } } -pub fn quote_var(args: &[LispExpr]) -> Result { - let arity = Arity::Exact(1); - if !arity.check(args) { - return Err(arity.to_error()); - } else { - return Ok(args[0].clone().quote(1)); +pub fn apply_quote(arg: &LispExpr) -> LispExpr { + match arg { + i @ LispExpr::Unit + | i @ LispExpr::StringLit(_) + | i @ LispExpr::Char(_) + | i @ LispExpr::Number(_) + | i @ LispExpr::BoolLit(_) => i.clone(), + LispExpr::List(ls) => LispExpr::List(ls.iter().map(|a| apply_quote(a)).collect::>()), + _ => arg.clone(), } } @@ -313,12 +316,28 @@ mod tests { assert!(run("(eq? '(1 2 3) '(1 2 3))", app).cast_bool()); assert!(run("(eq? '(1 '(1 2 3)) '(1 '(1 2 3)))", app).cast_bool(),); assert!(run("(eq? '#t '#t)", app).cast_bool()); + + assert!(run("(eq? 1 '1)", app).cast_bool()); + assert_eq!( + run("'(1 2 3)", app), + LispExpr::List( + vec![1, 2, 3] + .into_iter() + .map(LispNumber::Integer) + .map(LispExpr::Number) + .collect() + ), + ); + assert_eq!( + run("(caar (cdr '(1 (4 5))))", app), + LispExpr::Number(LispNumber::Integer(4)) + ); } fn eval_logical(app: &mut AppState) { assert!(run("(and #t #t)", app).cast_bool()); assert!(run("(or #f #t)", app).cast_bool()); - assert!(run("(not #t)", app).cast_bool()); + assert!(!run("(not #t)", app).cast_bool()); assert_eq!(run("(not #f)", app), run("(not (not #t))", app)); } } 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 @@ (filter pred (cdr ls))))) (define (member? item ls) - (if (null? ls) - #f - (or (eq? item (car ls)) - (member? item (cdr ls))))) + (fold #f + (lambda (acc x) (or acc (eq? item x))) + ls)) (define (assert expr) (assert-eq #t expr)) -- cgit v1.2.3