environ changes

This commit is contained in:
Able 2024-11-18 09:12:06 -06:00
parent 122fde0c40
commit fb8ded5ff6
4 changed files with 59 additions and 15 deletions

View file

@ -63,6 +63,32 @@ pub fn default_env<'a>() -> Environ<'a> {
}), }),
); );
data.insert(
"+".to_string(),
Expr::Func(|args: &[Expr]| -> Result<Expr, RispError> {
let sum = parse_list_of_floats(args)?
.iter()
.fold(0.0, |sum, a| sum + a);
Ok(Expr::Number(sum))
}),
);
data.insert(
"*".to_string(),
Expr::Func(|args: &[Expr]| -> Result<Expr, RispError> {
let floats = parse_list_of_floats(args)?;
let first = *floats.first().ok_or(RispError::Reason(
"expected at least one number".to_string(),
))?;
let sum_of_rest = floats[1..].iter().fold(0.0, |sum, a| sum + a);
Ok(Expr::Number(first * sum_of_rest))
}),
);
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(

View file

@ -1,4 +1,4 @@
use core::fmt; use std::fmt;
use core::num::ParseFloatError; use core::num::ParseFloatError;
pub use std::collections::HashMap; pub use std::collections::HashMap;
@ -21,7 +21,7 @@ mod evaluate;
pub enum RispError { pub enum RispError {
Reason(String), Reason(String),
} }
#[derive(Clone)] #[derive(Clone, Debug)]
pub enum Expr { pub enum Expr {
Bool(bool), Bool(bool),
Symbol(String), Symbol(String),
@ -31,7 +31,7 @@ pub enum Expr {
Func(fn(&[Expr]) -> Result<Expr, RispError>), Func(fn(&[Expr]) -> Result<Expr, RispError>),
Lambda(RLambda), Lambda(RLambda),
} }
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct RLambda { pub struct RLambda {
params_exp: Rc<Expr>, params_exp: Rc<Expr>,
body_exp: Rc<Expr>, body_exp: Rc<Expr>,
@ -47,10 +47,14 @@ impl fmt::Display for Expr {
Str(s) => format!("\"{}\"", s), Str(s) => format!("\"{}\"", s),
List(list) => { List(list) => {
let xs: Vec<String> = list.iter().map(|x| x.to_string()).collect(); let xs: Vec<String> = list.iter().map(|x| x.to_string()).collect();
format!("({})", xs.join(",")) format!("({})", xs.join(" "))
}
Func(func) => {
format!("({:?})", func)
}
Lambda(lambda) => {
format!("(fn {} {})", lambda.params_exp, lambda.body_exp)
} }
Func(_) => "Function {}".to_string(),
Lambda(_) => "Lambda {}".to_string(),
}; };
write!(f, "{}", str) write!(f, "{}", str)

View file

@ -44,7 +44,7 @@ fn parse_atom(token: &str) -> Expr {
let potential_float: Result<f64, ParseFloatError> = token.parse(); let potential_float: Result<f64, ParseFloatError> = token.parse();
match potential_float { match potential_float {
Ok(v) => Number(v), Ok(v) => Number(v),
Err(er) => { Err(_er) => {
if token.to_string().starts_with("\"") && token.to_string().ends_with("\""){ if token.to_string().starts_with("\"") && token.to_string().ends_with("\""){
let mut stri = token.to_string().clone(); let mut stri = token.to_string().clone();
stri.remove(0); stri.remove(0);

View file

@ -1,5 +1,4 @@
use std::collections::HashMap; #![allow(special_module_name)]
use std::fmt;
use std::io; use std::io;
use std::io::Write; use std::io::Write;
@ -20,29 +19,44 @@ fn slurp_expr() -> String {
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
println!("Exiting."); println!("Exiting.");
std::process::exit(0); std::process::exit(0);
#[allow(unreachable_code)]
Err(RispError::Reason("Cannot exit process".to_string())) Err(RispError::Reason("Cannot exit process".to_string()))
}), }),
); );
env.data.insert( env.data.insert(
"prompt".to_string(), "prompt".to_string(),
Expr::Symbol("risp => ".to_string()), Expr::Symbol("rlisp => ".to_string()),
); );
env
env.data.insert(
"print".to_string(),
Expr::Func(|args: &[Expr]| -> Result<Expr, RispError> {
let mut stri = String::new();
for arg in args {
let fmted = format!("{}", arg);
stri.push_str(&fmted);
stri.push_str(" ")
}
Ok(Expr::Symbol(stri.to_string()))
}),
);
env
} }
fn main() { fn main() {
let mut env = &mut default_env(); let env = &mut default_env();
let mut env = &mut extend_environ(env.clone()); let env = &mut extend_environ(env.clone());
loop { loop {
let prompt = env_get("prompt", env).unwrap_or(lib::Expr::Symbol("risp => ".to_string())); let prompt = env_get("prompt", env).unwrap_or(lib::Expr::Symbol("rlisp => ".to_string()));
print!("{}", prompt); print!("{}", prompt);
let _ = std::io::stdout().flush(); let _ = std::io::stdout().flush();
let expr = slurp_expr(); let expr = slurp_expr();