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(">".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(
|
||||||
|
|
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::Bool(_a) => Ok(exp.clone()),
|
||||||
Expr::Number(_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) => {
|
Expr::List(list) => {
|
||||||
let first_form = 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::Func(_) => Err(RispError::Reason("unexpected form".to_string())),
|
||||||
Expr::Lambda(_) => 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)),
|
"if" => Some(eval_if_args(arg_forms, env)),
|
||||||
"def" => Some(eval_def_args(arg_forms, env)),
|
"def" => Some(eval_def_args(arg_forms, env)),
|
||||||
"fn" => Some(eval_lambda_args(arg_forms)),
|
"fn" => Some(eval_lambda_args(arg_forms)),
|
||||||
|
"first" => Some(eval_first_args(arg_forms, env)),
|
||||||
|
"rest" => Some(eval_rest_args(arg_forms)),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
|
|
||||||
_ => 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> {
|
fn eval_lambda_args(arg_forms: &[Expr]) -> Result<Expr, RispError> {
|
||||||
let params_exp = arg_forms
|
let params_exp = arg_forms
|
||||||
|
|
4
src/lib/mod.rs
Normal file → Executable file
4
src/lib/mod.rs
Normal file → Executable file
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt;
|
|
||||||
use core::num::ParseFloatError;
|
use core::num::ParseFloatError;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
pub use std::collections::HashMap;
|
pub use std::collections::HashMap;
|
||||||
pub use std::io::Write;
|
pub use std::io::Write;
|
||||||
|
@ -7,8 +7,8 @@ pub use std::rc::Rc;
|
||||||
|
|
||||||
mod environ;
|
mod environ;
|
||||||
pub use environ::default_env;
|
pub use environ::default_env;
|
||||||
pub use environ::Environ;
|
|
||||||
pub use environ::env_get;
|
pub use environ::env_get;
|
||||||
|
pub use environ::Environ;
|
||||||
|
|
||||||
mod parser;
|
mod parser;
|
||||||
pub use parser::parse;
|
pub use parser::parse;
|
||||||
|
|
0
src/lib/parser.rs
Normal file → Executable file
0
src/lib/parser.rs
Normal file → Executable file
11
src/main.rs
Normal file → Executable file
11
src/main.rs
Normal file → Executable file
|
@ -1,3 +1,4 @@
|
||||||
|
#![feature(slice_take)]
|
||||||
#![allow(special_module_name)]
|
#![allow(special_module_name)]
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -15,7 +16,6 @@ fn slurp_expr() -> String {
|
||||||
expr
|
expr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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(),
|
||||||
|
@ -28,11 +28,8 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
env.data.insert(
|
env.data
|
||||||
"prompt".to_string(),
|
.insert("prompt".to_string(), Expr::Symbol("rlisp => ".to_string()));
|
||||||
Expr::Symbol("rlisp => ".to_string()),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
env.data.insert(
|
env.data.insert(
|
||||||
"print".to_string(),
|
"print".to_string(),
|
||||||
|
@ -50,8 +47,6 @@ fn extend_environ<'a>(mut env: Environ<'a>) -> Environ<'a> {
|
||||||
env
|
env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let env = &mut default_env();
|
let env = &mut default_env();
|
||||||
let env = &mut extend_environ(env.clone());
|
let env = &mut extend_environ(env.clone());
|
||||||
|
|
Loading…
Reference in a new issue