aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2021-03-29 07:42:15 +0100
committerAkshay <[email protected]>2021-03-29 07:42:15 +0100
commitf6e89e13d6b4db769f30b64408fc4b5995ab6cbb (patch)
tree0c24aee57b48ec2185f2c176b1b09e8d94fbae40
parent992141878227439cd517d05b68f15e57d77452a5 (diff)
functions are first class
-rw-r--r--src/lisp/eval.rs74
1 files changed, 40 insertions, 34 deletions
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<LispExpr, LispError>
30 "lambda" => create_lambda(&li[1..]), 30 "lambda" => create_lambda(&li[1..]),
31 "if" => eval_if(&li[1..], app), 31 "if" => eval_if(&li[1..], app),
32 _ => { 32 _ => {
33 let func_expr = eval(&func_expr, app)?; 33 let mut new_ls = vec![eval(&func_expr, app)?];
34 match func_expr { 34 new_ls.extend(li[1..].to_vec());
35 LispExpr::PrimitiveFunc(f) => { 35 eval(&(LispExpr::List(new_ls)), app)
36 let mut args = Vec::new();
37 for item in li[1..].iter() {
38 args.push(eval(item, app)?);
39 }
40 f.call(&args, app)
41 }
42 LispExpr::Function(f) => {
43 let mut args = Vec::new();
44 for item in li[1..].iter() {
45 let i = eval(item, app)?;
46 args.push(i);
47 }
48 if f.params.len() != args.len() {
49 info!("too many or too little number of args");
50 Err(EvalError::ArgumentCount(Arity::Exact(f.params.len()))
51 .into())
52 } else {
53 let nested_env: Environment =
54 f.params.into_iter().zip(args).collect();
55 app.lisp_env.push(nested_env);
56 let result = if f.body.is_empty() {
57 Ok(LispExpr::Unit)
58 } else {
59 eval(&LispExpr::List(f.body), app)
60 };
61 app.lisp_env.pop();
62 return result;
63 }
64 }
65 _ => Err(EvalError::BadForm.into()),
66 }
67 } 36 }
68 }, 37 },
38 LispExpr::PrimitiveFunc(f) => {
39 let mut args = Vec::new();
40 for item in li[1..].iter() {
41 args.push(eval(item, app)?);
42 }
43 f.call(&args, app)
44 }
45 LispExpr::Function(f) => {
46 let mut args = Vec::new();
47 for item in li[1..].iter() {
48 let i = eval(item, app)?;
49 args.push(i);
50 }
51 if f.params.len() != args.len() {
52 info!("too many or too little number of args");
53 Err(EvalError::ArgumentCount(Arity::Exact(f.params.len())).into())
54 } else {
55 let nested_env: Environment =
56 f.params.clone().into_iter().zip(args).collect();
57 app.lisp_env.push(nested_env);
58 let result = if f.body.is_empty() {
59 Ok(LispExpr::Unit)
60 } else {
61 eval(&LispExpr::List(f.body.clone()), app)
62 };
63 app.lisp_env.pop();
64 return result;
65 }
66 }
67 LispExpr::List(_) => {
68 info!("list as funciton");
69 let func_expr = eval(&func_expr, app)?;
70 let mut new_ls = vec![func_expr];
71 new_ls.extend(li[1..].to_vec());
72 eval(&(LispExpr::List(new_ls)), app)
73 }
69 _ => Err(EvalError::BadForm.into()), 74 _ => Err(EvalError::BadForm.into()),
70 } 75 }
71 } 76 }
@@ -74,6 +79,7 @@ pub fn eval(expr: &LispExpr, app: &mut AppState) -> Result<LispExpr, LispError>
74} 79}
75 80
76pub fn define_var(args: &[LispExpr], app: &mut AppState) -> Result<LispExpr, LispError> { 81pub fn define_var(args: &[LispExpr], app: &mut AppState) -> Result<LispExpr, LispError> {
82 info!("defining");
77 let arity = Arity::Exact(2); 83 let arity = Arity::Exact(2);
78 if !arity.is_valid(args) { 84 if !arity.is_valid(args) {
79 return Err(arity.to_error()); 85 return Err(arity.to_error());