From 4afc8ffdfe7ca2976bbab9d59da4c2ae11902c2f Mon Sep 17 00:00:00 2001 From: Akshay Date: Tue, 30 Mar 2021 19:33:46 +0530 Subject: add assert primitive; pass state in Evaluator --- src/lisp/prelude.rs | 57 +++++++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 35 deletions(-) (limited to 'src/lisp/prelude.rs') diff --git a/src/lisp/prelude.rs b/src/lisp/prelude.rs index dffd9f4..27e7ad2 100644 --- a/src/lisp/prelude.rs +++ b/src/lisp/prelude.rs @@ -2,7 +2,7 @@ use crate::{ brush::Brush, lisp::{ error::{EvalError, LispError}, - eval::eval, + eval::Evaluator, expr::{Arity, LispExpr}, number::LispNumber, Environment, @@ -21,6 +21,7 @@ macro_rules! primitive { let val = crate::lisp::expr::LispExpr::PrimitiveFunc(crate::lisp::expr::PrimitiveFunc { arity: $arity, closure: $closure, + name: $name, }); let _ = $env.insert($name.to_string(), val); }; @@ -241,41 +242,15 @@ pub fn new_env() -> Result { return Ok(LispExpr::Unit); }); - primitive!(env, Arity::Exact(2), "map", |args, app| { - let mut apply_map = - |func: &LispExpr, ls: &Vec| -> Result, LispError> { - ls.into_iter() - .map(|arg| eval(&LispExpr::List(vec![func.clone(), arg.clone()]), app)) - .collect() - }; - if matches!(&args[0], LispExpr::Function(_) | LispExpr::PrimitiveFunc(_)) { - match &args[1] { - LispExpr::List(ls) => return Ok(LispExpr::List(apply_map(&args[0], ls)?)), - _ => return Err(EvalError::TypeMismatch.into()), - } - } else { - return Err(EvalError::TypeMismatch.into()); - } - }); - - primitive!(env, Arity::Exact(2), "filter", |args, app| { - let mut apply_filter = - |func: &LispExpr, ls: &Vec| -> Result, LispError> { - let mut result = vec![]; - for arg in ls.into_iter() { - if eval(&LispExpr::List(vec![func.clone(), arg.clone()]), app)?.cast_bool() { - result.push(arg.clone()) - } - } - Ok(result) - }; - if matches!(&args[0], LispExpr::Function(_) | LispExpr::PrimitiveFunc(_)) { - match &args[1] { - LispExpr::List(ls) => return Ok(LispExpr::List(apply_filter(&args[0], ls)?)), - _ => return Err(EvalError::TypeMismatch.into()), - } + primitive!(env, Arity::Exact(2), "cons", |args, _| { + if type_match!(args, 1 => LispExpr::Unit) { + return Ok(LispExpr::List(vec![args[0].clone()])); + } else if !type_match!(args, 1 => LispExpr::List(_)) { + return Ok(LispExpr::List(vec![args[0].clone(), args[1].clone()])); } else { - return Err(EvalError::TypeMismatch.into()); + let mut rest = args[1].unwrap_list(); + rest.insert(0, args[0].clone()); + return Ok(LispExpr::List(rest)); } }); @@ -332,5 +307,17 @@ pub fn new_env() -> Result { } }); + primitive!(env, Arity::Exact(2), "assert-eq", |args, app| { + if args[0].compare(&args[1], &app.lisp_env)? { + return Ok(LispExpr::Unit); + } else { + return Err(EvalError::AssertionError { + expected: args[0].clone(), + got: args[1].clone(), + } + .into()); + } + }); + Ok(env) } -- cgit v1.2.3