From 122fde0c402c141749e42b40b42de2b8b60e981e Mon Sep 17 00:00:00 2001 From: Able Date: Fri, 15 Nov 2024 05:15:44 -0600 Subject: [PATCH] rearchitecturing --- assets/start.lisp | 1 + src/{ => lib}/environ.rs | 9 ++-- src/{ => lib}/evaluate.rs | 16 ++++--- src/lib/mod.rs | 74 +++++++++++++++++++++++++++++ src/{ => lib}/parser.rs | 26 ++++++++--- src/main.rs | 98 +++++++++++---------------------------- 6 files changed, 136 insertions(+), 88 deletions(-) rename src/{ => lib}/environ.rs (95%) rename src/{ => lib}/evaluate.rs (95%) create mode 100644 src/lib/mod.rs rename src/{ => lib}/parser.rs (69%) diff --git a/assets/start.lisp b/assets/start.lisp index e69de29..02ed4e6 100644 --- a/assets/start.lisp +++ b/assets/start.lisp @@ -0,0 +1 @@ +(def start (fn () (+ 1 1))) \ No newline at end of file diff --git a/src/environ.rs b/src/lib/environ.rs similarity index 95% rename from src/environ.rs rename to src/lib/environ.rs index 24f304e..8b414fd 100644 --- a/src/environ.rs +++ b/src/lib/environ.rs @@ -1,7 +1,7 @@ -use crate::parse_list_of_floats; -use crate::Expr; -use crate::HashMap; -use crate::RispError; +use crate::lib::parse_list_of_floats; +use crate::lib::Expr; +use crate::lib::HashMap; +use crate::lib::RispError; macro_rules! ensure_tonicity { ($check_fn:expr) => {{ @@ -49,6 +49,7 @@ pub fn default_env<'a>() -> Environ<'a> { Ok(Expr::Number(sum)) }), ); + data.insert( "-".to_string(), Expr::Func(|args: &[Expr]| -> Result { diff --git a/src/evaluate.rs b/src/lib/evaluate.rs similarity index 95% rename from src/evaluate.rs rename to src/lib/evaluate.rs index abdbfed..d99a1e5 100644 --- a/src/evaluate.rs +++ b/src/lib/evaluate.rs @@ -1,10 +1,10 @@ -use crate::environ::env_get; -use crate::Environ; -use crate::Expr; -use crate::HashMap; -use crate::RLambda; -use crate::Rc; -use crate::RispError; +use crate::lib::environ::env_get; +use crate::lib::Environ; +use crate::lib::Expr; +use crate::lib::HashMap; +use crate::lib::RLambda; +use crate::lib::Rc; +use crate::lib::RispError; pub fn eval(exp: &Expr, env: &mut Environ) -> Result { match exp { @@ -14,6 +14,8 @@ 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::List(list) => { let first_form = list .first() diff --git a/src/lib/mod.rs b/src/lib/mod.rs new file mode 100644 index 0000000..448289b --- /dev/null +++ b/src/lib/mod.rs @@ -0,0 +1,74 @@ +use core::fmt; +use core::num::ParseFloatError; + +pub use std::collections::HashMap; +pub use std::io::Write; +pub use std::rc::Rc; + +mod environ; +pub use environ::default_env; +pub use environ::Environ; +pub use environ::env_get; + +mod parser; +pub use parser::parse; +pub use parser::parse_eval; +pub use parser::parse_list_of_floats; + +mod evaluate; + +#[derive(Debug)] +pub enum RispError { + Reason(String), +} +#[derive(Clone)] +pub enum Expr { + Bool(bool), + Symbol(String), + Number(f64), + Str(String), + List(Vec), + Func(fn(&[Expr]) -> Result), + Lambda(RLambda), +} +#[derive(Clone)] +pub struct RLambda { + params_exp: Rc, + body_exp: Rc, +} + +impl fmt::Display for Expr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + use Expr::*; + let str = match self { + Bool(a) => a.to_string(), + Symbol(s) => s.clone(), + Number(n) => n.to_string(), + Str(s) => format!("\"{}\"", s), + List(list) => { + let xs: Vec = list.iter().map(|x| x.to_string()).collect(); + format!("({})", xs.join(",")) + } + Func(_) => "Function {}".to_string(), + Lambda(_) => "Lambda {}".to_string(), + }; + + write!(f, "{}", str) + } +} + +fn read_seq<'a>(tokens: &'a [String]) -> Result<(Expr, &'a [String]), RispError> { + let mut res: Vec = vec![]; + let mut xs = tokens; + loop { + let (next_token, rest) = xs + .split_first() + .ok_or(RispError::Reason("could not find closing `)`".to_string()))?; + if next_token == ")" { + return Ok((Expr::List(res), rest)); // skip `)`, head to the token after + } + let (exp, new_xs) = parse(&xs)?; + res.push(exp); + xs = new_xs; + } +} diff --git a/src/parser.rs b/src/lib/parser.rs similarity index 69% rename from src/parser.rs rename to src/lib/parser.rs index 9fc603e..d889d9a 100644 --- a/src/parser.rs +++ b/src/lib/parser.rs @@ -1,9 +1,9 @@ -use crate::evaluate::eval; -use crate::read_seq; -use crate::Environ; -use crate::Expr; -use crate::ParseFloatError; -use crate::RispError; +use crate::lib::evaluate::eval; +use crate::lib::read_seq; +use crate::lib::Environ; +use crate::lib::Expr; +use crate::lib::ParseFloatError; +use crate::lib::RispError; pub fn tokenize(expr: String) -> Vec { expr.replace("(", " ( ") @@ -44,7 +44,19 @@ fn parse_atom(token: &str) -> Expr { let potential_float: Result = token.parse(); match potential_float { Ok(v) => Number(v), - Err(_) => Symbol(token.to_string().clone()), + Err(er) => { + if token.to_string().starts_with("\"") && token.to_string().ends_with("\""){ + let mut stri = token.to_string().clone(); + stri.remove(0); + stri.pop(); + + Str(stri) + }else{ + + + Symbol(token.to_string().clone()) + } + } } } } diff --git a/src/main.rs b/src/main.rs index ef73873..2f645e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,75 +2,9 @@ use std::collections::HashMap; use std::fmt; use std::io; use std::io::Write; -use std::num::ParseFloatError; -use std::rc::Rc; -mod environ; -use environ::default_env; -use environ::Environ; - -mod parser; -use parser::parse; -use parser::parse_eval; -use parser::parse_list_of_floats; - -mod evaluate; - -#[derive(Debug)] -enum RispError { - Reason(String), -} - -#[derive(Clone)] -enum Expr { - Bool(bool), - Symbol(String), - Number(f64), - List(Vec), - Func(fn(&[Expr]) -> Result), - Lambda(RLambda), -} - -#[derive(Clone)] -struct RLambda { - params_exp: Rc, - body_exp: Rc, -} - -impl fmt::Display for Expr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use Expr::*; - let str = match self { - Bool(a) => a.to_string(), - Symbol(s) => s.clone(), - Number(n) => n.to_string(), - List(list) => { - let xs: Vec = list.iter().map(|x| x.to_string()).collect(); - format!("({})", xs.join(",")) - } - Func(_) => "Function {}".to_string(), - Lambda(_) => "Lambda {}".to_string(), - }; - - write!(f, "{}", str) - } -} - -fn read_seq<'a>(tokens: &'a [String]) -> Result<(Expr, &'a [String]), RispError> { - let mut res: Vec = vec![]; - let mut xs = tokens; - loop { - let (next_token, rest) = xs - .split_first() - .ok_or(RispError::Reason("could not find closing `)`".to_string()))?; - if next_token == ")" { - return Ok((Expr::List(res), rest)); // skip `)`, head to the token after - } - let (exp, new_xs) = parse(&xs)?; - res.push(exp); - xs = new_xs; - } -} +mod lib; +use lib::*; fn slurp_expr() -> String { let mut expr = String::new(); @@ -82,10 +16,34 @@ fn slurp_expr() -> String { expr } + +fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> { + env.data.insert( + "quit".to_string(), + Expr::Func(|args: &[Expr]| -> Result { + // TODO: let this function take in arguments + println!("Exiting."); + std::process::exit(0); + Err(RispError::Reason("Cannot exit process".to_string())) + }), + ); + + env.data.insert( + "prompt".to_string(), + Expr::Symbol("risp => ".to_string()), + ); + +env +} + + + fn main() { - let env = &mut default_env(); + let mut env = &mut default_env(); + let mut env = &mut extend_environ(env.clone()); loop { - print!("risp > "); + let prompt = env_get("prompt", env).unwrap_or(lib::Expr::Symbol("risp => ".to_string())); + print!("{}", prompt); let _ = std::io::stdout().flush(); let expr = slurp_expr(); match parse_eval(expr, env) {