diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/Cargo.lock b/Cargo.lock old mode 100644 new mode 100755 diff --git a/Cargo.toml b/Cargo.toml old mode 100644 new mode 100755 diff --git a/assets/start.lisp b/assets/start.lisp old mode 100644 new mode 100755 diff --git a/rust-toolchain.toml b/rust-toolchain.toml old mode 100644 new mode 100755 diff --git a/shell.nix b/shell.nix old mode 100644 new mode 100755 diff --git a/src/lib/environ.rs b/src/lib/environ.rs old mode 100644 new mode 100755 index c1b1f60..4991441 --- a/src/lib/environ.rs +++ b/src/lib/environ.rs @@ -87,8 +87,6 @@ pub fn default_env<'a>() -> Environ<'a> { }), ); - - data.insert("=".to_string(), Expr::Func(ensure_tonicity!(|a, b| a == b))); data.insert(">".to_string(), Expr::Func(ensure_tonicity!(|a, b| a > b))); data.insert( diff --git a/src/lib/evaluate.rs b/src/lib/evaluate.rs old mode 100644 new mode 100755 index d99a1e5..40cc9aa --- a/src/lib/evaluate.rs +++ b/src/lib/evaluate.rs @@ -14,7 +14,7 @@ pub fn eval(exp: &Expr, env: &mut Environ) -> Result { Expr::Bool(_a) => Ok(exp.clone()), Expr::Number(_a) => Ok(exp.clone()), - Expr::Str(_a)=>{ Ok(exp.clone())} + Expr::Str(_a) => Ok(exp.clone()), Expr::List(list) => { let first_form = list @@ -40,6 +40,7 @@ pub fn eval(exp: &Expr, env: &mut Environ) -> Result { } Expr::Func(_) => Err(RispError::Reason("unexpected form".to_string())), Expr::Lambda(_) => Err(RispError::Reason("unexpected form".to_string())), + // Expr::Nil => Err(RispError::Reason("unexpected nil".to_string())), } } @@ -98,12 +99,48 @@ fn eval_built_in_form( "if" => Some(eval_if_args(arg_forms, env)), "def" => Some(eval_def_args(arg_forms, env)), "fn" => Some(eval_lambda_args(arg_forms)), + "first" => Some(eval_first_args(arg_forms, env)), + "rest" => Some(eval_rest_args(arg_forms)), _ => None, }, _ => None, } } +fn eval_first_args(arg_forms: &[Expr], env: &mut Environ) -> Result { + if arg_forms.first().is_some() { + let first = arg_forms.first().unwrap(); + let ret: Result = match first { + Expr::List(vec) => Ok(vec.first().unwrap().clone()), + // Expr::Func(a) => a(), + Expr::Lambda(lambda) => eval(&Expr::Lambda(lambda.clone()), env), + _ => Ok(Expr::List(Vec::new())), + }; + return Ok(ret.unwrap()); + } else { + Ok(Expr::List(Vec::new())) + } +} + +fn eval_rest_args(mut arg_forms: &[Expr]) -> Result { + if arg_forms.first().is_some() { + // let first = arg_forms.first().unwrap(); + let first = arg_forms.take_first().unwrap(); + match first { + Expr::List(vec) => { + let mut rest_vec = vec.clone(); + if rest_vec.len() == 0 { + return Ok(Expr::List(Vec::new())); + } + let _first = rest_vec.remove(0); + + return Ok(Expr::List(rest_vec.to_vec())); + } + _ => return Ok(Expr::List(Vec::new())), + } + } + Ok(Expr::List(Vec::new())) +} fn eval_lambda_args(arg_forms: &[Expr]) -> Result { let params_exp = arg_forms diff --git a/src/lib/mod.rs b/src/lib/mod.rs old mode 100644 new mode 100755 index 7270440..ff7ced6 --- a/src/lib/mod.rs +++ b/src/lib/mod.rs @@ -1,5 +1,5 @@ -use std::fmt; use core::num::ParseFloatError; +use std::fmt; pub use std::collections::HashMap; pub use std::io::Write; @@ -7,8 +7,8 @@ pub use std::rc::Rc; mod environ; pub use environ::default_env; -pub use environ::Environ; pub use environ::env_get; +pub use environ::Environ; mod parser; pub use parser::parse; @@ -53,7 +53,7 @@ impl fmt::Display for Expr { format!("({:?})", func) } Lambda(lambda) => { - format!("(fn {} {})", lambda.params_exp, lambda.body_exp) + format!("(fn {} {})", lambda.params_exp, lambda.body_exp) } }; diff --git a/src/lib/parser.rs b/src/lib/parser.rs old mode 100644 new mode 100755 diff --git a/src/main.rs b/src/main.rs old mode 100644 new mode 100755 index 937cf17..266225b --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +#![feature(slice_take)] #![allow(special_module_name)] use std::io; use std::io::Write; @@ -15,9 +16,8 @@ fn slurp_expr() -> String { expr } - fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> { - env.data.insert( + env.data.insert( "quit".to_string(), Expr::Func(|_args: &[Expr]| -> Result { // TODO: let this function take in arguments @@ -28,11 +28,8 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> { }), ); - env.data.insert( - "prompt".to_string(), - Expr::Symbol("rlisp => ".to_string()), - ); - + env.data + .insert("prompt".to_string(), Expr::Symbol("rlisp => ".to_string())); env.data.insert( "print".to_string(), @@ -43,15 +40,13 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> { stri.push_str(&fmted); stri.push_str(" ") } - + Ok(Expr::Symbol(stri.to_string())) }), ); env } - - fn main() { let env = &mut default_env(); let env = &mut extend_environ(env.clone());