From f6e89e13d6b4db769f30b64408fc4b5995ab6cbb Mon Sep 17 00:00:00 2001 From: Akshay Date: Mon, 29 Mar 2021 12:12:15 +0530 Subject: functions are first class --- src/lisp/eval.rs | 74 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 34 deletions(-) (limited to 'src/lisp') diff --git a/src/lisp/eval.rs b/src/lisp/eval.rs index f49efb9..3a3a61e 100644 --- a/src/lisp/eval.rs +++ b/src/lisp/eval.rs @@ -30,42 +30,47 @@ pub fn eval(expr: &LispExpr, app: &mut AppState) -> Result "lambda" => create_lambda(&li[1..]), "if" => eval_if(&li[1..], app), _ => { - let func_expr = eval(&func_expr, app)?; - match func_expr { - LispExpr::PrimitiveFunc(f) => { - let mut args = Vec::new(); - for item in li[1..].iter() { - args.push(eval(item, app)?); - } - f.call(&args, app) - } - LispExpr::Function(f) => { - let mut args = Vec::new(); - for item in li[1..].iter() { - let i = eval(item, app)?; - args.push(i); - } - if f.params.len() != args.len() { - info!("too many or too little number of args"); - Err(EvalError::ArgumentCount(Arity::Exact(f.params.len())) - .into()) - } else { - let nested_env: Environment = - f.params.into_iter().zip(args).collect(); - app.lisp_env.push(nested_env); - let result = if f.body.is_empty() { - Ok(LispExpr::Unit) - } else { - eval(&LispExpr::List(f.body), app) - }; - app.lisp_env.pop(); - return result; - } - } - _ => Err(EvalError::BadForm.into()), - } + let mut new_ls = vec![eval(&func_expr, app)?]; + new_ls.extend(li[1..].to_vec()); + eval(&(LispExpr::List(new_ls)), app) } }, + LispExpr::PrimitiveFunc(f) => { + let mut args = Vec::new(); + for item in li[1..].iter() { + args.push(eval(item, app)?); + } + f.call(&args, app) + } + LispExpr::Function(f) => { + let mut args = Vec::new(); + for item in li[1..].iter() { + let i = eval(item, app)?; + args.push(i); + } + if f.params.len() != args.len() { + info!("too many or too little number of args"); + Err(EvalError::ArgumentCount(Arity::Exact(f.params.len())).into()) + } else { + let nested_env: Environment = + f.params.clone().into_iter().zip(args).collect(); + app.lisp_env.push(nested_env); + let result = if f.body.is_empty() { + Ok(LispExpr::Unit) + } else { + eval(&LispExpr::List(f.body.clone()), app) + }; + app.lisp_env.pop(); + return result; + } + } + LispExpr::List(_) => { + info!("list as funciton"); + let func_expr = eval(&func_expr, app)?; + let mut new_ls = vec![func_expr]; + new_ls.extend(li[1..].to_vec()); + eval(&(LispExpr::List(new_ls)), app) + } _ => Err(EvalError::BadForm.into()), } } @@ -74,6 +79,7 @@ pub fn eval(expr: &LispExpr, app: &mut AppState) -> Result } pub fn define_var(args: &[LispExpr], app: &mut AppState) -> Result { + info!("defining"); let arity = Arity::Exact(2); if !arity.is_valid(args) { return Err(arity.to_error()); -- cgit v1.2.3