implement broken first and rest functions

This commit is contained in:
Able 2024-12-03 12:05:04 -06:00
parent fb8ded5ff6
commit 553dbd6aad
11 changed files with 46 additions and 16 deletions

0
.gitignore vendored Normal file → Executable file
View file

0
Cargo.lock generated Normal file → Executable file
View file

0
Cargo.toml Normal file → Executable file
View file

0
assets/start.lisp Normal file → Executable file
View file

0
rust-toolchain.toml Normal file → Executable file
View file

0
shell.nix Normal file → Executable file
View file

2
src/lib/environ.rs Normal file → Executable file
View file

@ -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(">".to_string(), Expr::Func(ensure_tonicity!(|a, b| a > b))); data.insert(">".to_string(), Expr::Func(ensure_tonicity!(|a, b| a > b)));
data.insert( data.insert(

39
src/lib/evaluate.rs Normal file → Executable file
View file

@ -14,7 +14,7 @@ pub fn eval(exp: &Expr, env: &mut Environ) -> Result<Expr, RispError> {
Expr::Bool(_a) => Ok(exp.clone()), Expr::Bool(_a) => Ok(exp.clone()),
Expr::Number(_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) => { Expr::List(list) => {
let first_form = list let first_form = list
@ -40,6 +40,7 @@ pub fn eval(exp: &Expr, env: &mut Environ) -> Result<Expr, RispError> {
} }
Expr::Func(_) => Err(RispError::Reason("unexpected form".to_string())), Expr::Func(_) => Err(RispError::Reason("unexpected form".to_string())),
Expr::Lambda(_) => 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)), "if" => Some(eval_if_args(arg_forms, env)),
"def" => Some(eval_def_args(arg_forms, env)), "def" => Some(eval_def_args(arg_forms, env)),
"fn" => Some(eval_lambda_args(arg_forms)), "fn" => Some(eval_lambda_args(arg_forms)),
"first" => Some(eval_first_args(arg_forms, env)),
"rest" => Some(eval_rest_args(arg_forms)),
_ => None, _ => None,
}, },
_ => None, _ => None,
} }
} }
fn eval_first_args(arg_forms: &[Expr], env: &mut Environ) -> Result<Expr, RispError> {
if arg_forms.first().is_some() {
let first = arg_forms.first().unwrap();
let ret: Result<Expr, RispError> = 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<Expr, RispError> {
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<Expr, RispError> { fn eval_lambda_args(arg_forms: &[Expr]) -> Result<Expr, RispError> {
let params_exp = arg_forms let params_exp = arg_forms

4
src/lib/mod.rs Normal file → Executable file
View file

@ -1,5 +1,5 @@
use std::fmt;
use core::num::ParseFloatError; use core::num::ParseFloatError;
use std::fmt;
pub use std::collections::HashMap; pub use std::collections::HashMap;
pub use std::io::Write; pub use std::io::Write;
@ -7,8 +7,8 @@ pub use std::rc::Rc;
mod environ; mod environ;
pub use environ::default_env; pub use environ::default_env;
pub use environ::Environ;
pub use environ::env_get; pub use environ::env_get;
pub use environ::Environ;
mod parser; mod parser;
pub use parser::parse; pub use parser::parse;

0
src/lib/parser.rs Normal file → Executable file
View file

13
src/main.rs Normal file → Executable file
View file

@ -1,3 +1,4 @@
#![feature(slice_take)]
#![allow(special_module_name)] #![allow(special_module_name)]
use std::io; use std::io;
use std::io::Write; use std::io::Write;
@ -15,9 +16,8 @@ fn slurp_expr() -> String {
expr expr
} }
fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> { fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> {
env.data.insert( env.data.insert(
"quit".to_string(), "quit".to_string(),
Expr::Func(|_args: &[Expr]| -> Result<Expr, RispError> { Expr::Func(|_args: &[Expr]| -> Result<Expr, RispError> {
// TODO: let this function take in arguments // TODO: let this function take in arguments
@ -28,11 +28,8 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> {
}), }),
); );
env.data.insert( env.data
"prompt".to_string(), .insert("prompt".to_string(), Expr::Symbol("rlisp => ".to_string()));
Expr::Symbol("rlisp => ".to_string()),
);
env.data.insert( env.data.insert(
"print".to_string(), "print".to_string(),
@ -50,8 +47,6 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> {
env env
} }
fn main() { fn main() {
let env = &mut default_env(); let env = &mut default_env();
let env = &mut extend_environ(env.clone()); let env = &mut extend_environ(env.clone());