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(

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::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, RispError> {
}
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<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> {
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 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;

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)]
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<Expr, RispError> {
// 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(),
@ -50,8 +47,6 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> {
env
}
fn main() {
let env = &mut default_env();
let env = &mut extend_environ(env.clone());