implement broken first and rest functions
This commit is contained in:
parent
fb8ded5ff6
commit
553dbd6aad
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
0
Cargo.lock
generated
Normal file → Executable file
0
Cargo.lock
generated
Normal file → Executable file
0
Cargo.toml
Normal file → Executable file
0
Cargo.toml
Normal file → Executable file
0
assets/start.lisp
Normal file → Executable file
0
assets/start.lisp
Normal file → Executable file
0
rust-toolchain.toml
Normal file → Executable file
0
rust-toolchain.toml
Normal file → Executable file
2
src/lib/environ.rs
Normal file → Executable file
2
src/lib/environ.rs
Normal file → Executable 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
39
src/lib/evaluate.rs
Normal file → Executable 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
|
||||
|
|
6
src/lib/mod.rs
Normal file → Executable file
6
src/lib/mod.rs
Normal file → Executable 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;
|
||||
|
@ -53,7 +53,7 @@ impl fmt::Display for Expr {
|
|||
format!("({:?})", func)
|
||||
}
|
||||
Lambda(lambda) => {
|
||||
format!("(fn {} {})", lambda.params_exp, lambda.body_exp)
|
||||
format!("(fn {} {})", lambda.params_exp, lambda.body_exp)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
0
src/lib/parser.rs
Normal file → Executable file
0
src/lib/parser.rs
Normal file → Executable file
15
src/main.rs
Normal file → Executable file
15
src/main.rs
Normal file → Executable 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(),
|
||||
|
@ -43,15 +40,13 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> {
|
|||
stri.push_str(&fmted);
|
||||
stri.push_str(" ")
|
||||
}
|
||||
|
||||
|
||||
Ok(Expr::Symbol(stri.to_string()))
|
||||
}),
|
||||
);
|
||||
env
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn main() {
|
||||
let env = &mut default_env();
|
||||
let env = &mut extend_environ(env.clone());
|
||||
|
|
Loading…
Reference in a new issue