environ changes
This commit is contained in:
parent
122fde0c40
commit
fb8ded5ff6
|
@ -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(
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
30
src/main.rs
30
src/main.rs
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue