diff --git a/src/bin/main.rs b/src/bin/main.rs
deleted file mode 100644
index 9565a5a..0000000
--- a/src/bin/main.rs
+++ /dev/null
@@ -1,147 +0,0 @@
-/* relish: versatile lisp shell
- * Copyright (C) 2021 Aidan Hahn
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-use dirs::home_dir;
-use relish::ast::{ast_to_string, eval, func_call, lex, new_ast, Ctr, FTable, VTable};
-use relish::aux::configure;
-use rustyline::error::ReadlineError;
-use rustyline::Editor;
-use std::cell::RefCell;
-use std::env;
-use std::rc::Rc;
-
-fn main() {
- let mut rl = Editor::<()>::new();
-
- const HIST_FILE: &str = "/.relish_hist";
- const CONFIG_FILE_DEFAULT: &str = "/.relishrc";
-
- let mut hist: String = "".to_owned();
- let mut cfg: String = "".to_owned();
-
- if let Some(home) = home_dir() {
- if let Some(h) = home.to_str() {
- hist = h.to_owned() + HIST_FILE;
- cfg = h.to_owned() + CONFIG_FILE_DEFAULT;
- }
- }
-
- if hist != "" {
- // ignore result. it loads or it doesnt.
- let _ = rl.load_history(&hist);
- }
-
- let vt = Rc::new(RefCell::new(VTable::new()));
- let conf_file;
- let ft;
- match env::var("RELISH_CFG_FILE") {
- Ok(s) => {
- conf_file = s
- },
- Err(e) => {
- eprintln!("{}", e);
- conf_file = cfg;
- },
- }
-
- match configure(conf_file, vt.clone()) {
- Ok(f) => ft = f,
- Err(e) => {
- ft = Rc::new(RefCell::new(FTable::new()));
- eprintln!("{}", e);
- },
- }
-
- loop {
- let readline: Result;
- // Rust is pain
- let tmp_ft_clone = ft.clone();
- // this is not okay
- let t_ft_c_b = tmp_ft_clone.borrow();
- let pfunc = t_ft_c_b.get("CFG_RELISH_PROMPT");
- if let Some(fnc) = pfunc {
- match func_call(
- fnc.clone(),
- new_ast(Ctr::None, Ctr::None),
- vt.clone(),
- ft.clone(),
- ) {
- Err(s) => {
- eprintln!("Couldnt generate prompt: {}", s);
- readline = rl.readline("");
- }
-
- Ok(c) => match c {
- Ctr::Symbol(s) => readline = rl.readline(&s.to_owned()),
- Ctr::String(s) => readline = rl.readline(&s),
- Ctr::Integer(i) => readline = rl.readline(&format!("{}", i)),
- Ctr::Float(f) => readline = rl.readline(&format!("{}", f)),
- Ctr::Bool(b) => readline = rl.readline(&format!("{}", b)),
- Ctr::Seg(c) => readline = rl.readline(&ast_to_string(c.clone())),
- Ctr::None => readline = rl.readline(""),
- },
- }
- } else {
- readline = rl.readline("");
- }
-
- match readline {
- Ok(line) => {
- rl.add_history_entry(line.as_str());
- let mut l = line.as_str().to_owned();
- if !l.starts_with("(") {
- l = "(".to_owned() + &l;
- }
-
- if !l.ends_with(")") {
- l = l + ")";
- }
-
- match lex(l) {
- Ok(a) => match eval(a.clone(), vt.clone(), ft.clone(), false) {
- Ok(a) => match a {
- Ctr::Symbol(s) => println!("{}", s),
- Ctr::String(s) => println!("{}", s),
- Ctr::Integer(i) => println!("{}", i),
- Ctr::Float(f) => println!("{}", f),
- Ctr::Bool(b) => println!("{}", b),
- Ctr::Seg(c) => println!("{}", ast_to_string(c.clone())),
- Ctr::None => (),
- },
- Err(s) => {
- println!("{}", s);
- }
- },
- Err(s) => {
- println!("{}", s);
- }
- }
- }
-
- Err(ReadlineError::Interrupted) => break,
-
- Err(ReadlineError::Eof) => return,
- Err(err) => {
- eprintln!("Prompt error: {:?}", err);
- break;
- }
- }
- }
- if hist != "" {
- rl.save_history(&hist).unwrap();
- }
-}
diff --git a/src/control.rs b/src/control.rs
deleted file mode 100644
index 9032397..0000000
--- a/src/control.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-/* relish: versatile lisp shell
- * Copyright (C) 2021 Aidan Hahn
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-use crate::append::get_append;
-use crate::func::{func_declare, FTable, Ast};
-use crate::segment::Ctr;
-use crate::str::{get_concat, get_echo};
-use crate::vars::{get_export, VTable};
-use std::cell::RefCell;
-use std::rc::Rc;
-
-pub fn get_if() -> Function {
- return Function {
- name: String::from("if"),
- loose_syms: false,
- eval_lazy: true,
- args: Args::Lazy(-1),
- function: Operation::Internal(
- Box::new(|args: Ast, vars: Rc>, funcs: Rc>| -> Ctr {
- // Either 2 long or 3 long.
- // arg 1 must eval to a bool
- // then eval arg 2 or 3
- })
- ),
- };
-}
diff --git a/src/lib.rs b/src/lib.rs
index 1a34393..4dfaebe 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,16 +15,13 @@
* along with this program. If not, see .
*/
-/*mod append;
-mod config;
- */
+
+//mod config;
mod eval;
mod lex;
mod segment;
mod sym;
mod stl;
-/*mod stl;
-mod str;*/
pub mod ast {
pub use crate::eval::eval;
@@ -36,12 +33,9 @@ pub mod ast {
};
}
-/*pub mod stdlib {
- pub use crate::append::get_append;
- pub use crate::stl::get_stdlib;
- pub use crate::str::{get_concat, get_echo};
- pub use crate::vars::get_export;
-}*/
+pub mod stdlib {
+ pub use crate::stl::{static_stdlib, dynamic_stdlib};
+}
/*pub mod aux {
pub use crate::config::configure;
diff --git a/src/stl.rs b/src/stl.rs
index c74cf8a..e63d0f1 100644
--- a/src/stl.rs
+++ b/src/stl.rs
@@ -21,35 +21,56 @@ use crate::sym::{SymTable, Symbol, ValueType, Args, UserFn};
use std::env;
use std::rc::Rc;
-fn store_stdlib(env: bool, syms: &mut SymTable) -> Result<(), String> {
- syms.insert("def".to_string(), Symbol {
- name: String::from("export"),
- args: Args::Lazy(2),
- conditional_branches: false,
- value: ValueType::Internal(Rc::new( move |ast: &Seg, syms: &mut SymTable| -> Ctr {
- _store_callback(ast, syms, env)
- },
- )),
- });
+pub mod control;
+pub mod append;
+//pub mod str;
+/// static_stdlib
+/// inserts all stdlib functions that can be inserted without
+/// any kind of further configuration data into a symtable
+pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
syms.insert("append".to_string(), Symbol {
name: String::from("append"),
args: Args::Infinite,
conditional_branches: false,
- value: ValueType::Internal(Rc::new(_append_callback)),
+ value: ValueType::Internal(Rc::new(append::append_callback)),
+ });
+
+ syms.insert("expand".to_string(), Symbol {
+ name: String::from("expand"),
+ args: Args::Strict(vec![Type::Seg]),
+ conditional_branches: false,
+ value: ValueType::Internal(Rc::new(append::expand_callback)),
+ });
+
+ syms.insert("if".to_string(), Symbol {
+ name: String::from("if"),
+ args: Args::Lazy(3),
+ conditional_branches: true,
+ value: ValueType::Internal(Rc::new(control::if_callback)),
});
Ok(())
}
+/// dynamic_stdlib
+/// takes configuration data and uses it to insert dynamic
+/// callbacks with configuration into a symtable
+pub fn dynamic_stdlib(env: bool, syms: &mut SymTable) -> Result<(), String> {
+ syms.insert("def".to_string(), Symbol {
+ name: String::from("export"),
+ args: Args::Lazy(2),
+ conditional_branches: false,
+ value: ValueType::Internal(Rc::new( move |ast: &Seg, syms: &mut SymTable| -> Result {
+ _store_callback(ast, syms, env)
+ },
+ )),
+ });
-fn _append_callback (_ast: &Seg, _syms: &mut SymTable) -> Ctr {
- // if car is a list, append cdr
- // otherwise create a list out of all arguments
- todo!()
+ Ok(())
}
-fn _store_callback (ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Ctr {
+fn _store_callback (ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Result {
let is_var = ast.len() == 2;
if let Ctr::Symbol(ref identifier) = *ast.car {
match &*ast.cdr {
@@ -65,9 +86,9 @@ fn _store_callback (ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Ctr {
env::set_var(identifier.clone(), val.car.to_string());
}
} else {
- eprintln!("impossible args to export")
+ return Err("impossible args to export".to_string());
},
- Err(e) => eprintln!("couldnt eval symbol: {}", e),
+ Err(e) => return Err(format!("couldnt eval symbol: {}", e)),
},
Ctr::Seg(data_tree) if !is_var => {
if let Ctr::Seg(ref args) = *data_tree.car {
@@ -80,8 +101,7 @@ fn _store_callback (ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Ctr {
false
}
}) {
- eprintln!("all arguments defined for function must be of type symbol");
- return Ctr::None;
+ return Err("all arguments defined for function must be of type symbol".to_string());
};
if let Ctr::Seg(ref bodies) = *data_tree.cdr {
@@ -98,12 +118,10 @@ fn _store_callback (ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Ctr {
conditional_branches: false,
});
} else {
- eprintln!("expected one or more function bodies in function definition");
- return Ctr::None;
+ return Err("expected one or more function bodies in function definition".to_string());
}
} else {
- eprintln!("expected list of arguments in function definition");
- return Ctr::None;
+ return Err("expected list of arguments in function definition".to_string());
}
}
Ctr::None => {
@@ -112,11 +130,11 @@ fn _store_callback (ast: &Seg, syms: &mut SymTable, env_cfg: bool) -> Ctr {
env::remove_var(identifier);
}
},
- _ => eprintln!("args not in standard form"),
+ _ => return Err("args not in standard form".to_string()),
}
} else {
- eprintln!("first argument to export must be a symbol");
+ return Err("first argument to export must be a symbol".to_string());
}
- Ctr::None
+ Ok(Ctr::None)
}
diff --git a/src/stl/append.rs b/src/stl/append.rs
new file mode 100644
index 0000000..1e46fa2
--- /dev/null
+++ b/src/stl/append.rs
@@ -0,0 +1,52 @@
+/* Copyright (C) 2021 Aidan Hahn
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+use crate::segment::{Ctr, Seg};
+use crate::sym::{SymTable};
+
+// Some essential operations below
+pub fn append_callback (ast: &Seg, _syms: &mut SymTable) -> Result {
+ // if car is a list, append cdr
+ // otherwise create a list out of all arguments
+ if let Ctr::Seg(ref s) = *ast.car {
+ let mut temp = s.clone();
+ temp.append(ast.cdr.clone());
+ Ok(Ctr::Seg(temp))
+ } else {
+ let mut temp = Seg::new();
+ let mut car_iter = &ast.car;
+ let mut cdr_iter = &ast.cdr;
+ loop {
+ temp.append(car_iter.clone());
+ if let Ctr::Seg(ref s) = **cdr_iter {
+ car_iter = &s.car;
+ cdr_iter = &s.cdr;
+ } else {
+ break;
+ }
+ }
+
+ Ok(Ctr::Seg(temp))
+ }
+}
+
+pub fn expand_callback (ast: &Seg, _syms: &mut SymTable) -> Result {
+ if let Ctr::Seg(_) = *ast.car {
+ Ok(*ast.car.clone())
+ } else {
+ Err("non list passed to expand!".to_string())
+ }
+}
diff --git a/src/stl/control.rs b/src/stl/control.rs
new file mode 100644
index 0000000..4a4c801
--- /dev/null
+++ b/src/stl/control.rs
@@ -0,0 +1,62 @@
+/* relish: versatile lisp shell
+ * Copyright (C) 2021 Aidan Hahn
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+use crate::segment::{Ctr, Seg};
+use crate::eval::eval;
+use crate::sym::SymTable;
+
+pub fn if_callback (ast: &Seg, syms: &mut SymTable) -> Result {
+ if let Ctr::Seg(ref cond_form) = *ast.car {
+ if let Ctr::Bool(cond) = *eval(cond_form, syms)? {
+ if let Ctr::Seg(ref first_form) = *ast.cdr {
+ if cond {
+ match *first_form.car {
+ Ctr::Seg(ref first_arg) => Ok(*eval(first_arg, syms)?),
+ _ => Ok(*eval(&Seg::from_mono(first_form.car.clone()), syms)?),
+ }
+ } else {
+ if let Ctr::Seg(ref second_form) = *first_form.cdr {
+ match *second_form.car {
+ Ctr::Seg(ref second_arg) => Ok(*eval(second_arg, syms)?),
+ _ => Ok(*eval(&Seg::from_mono(second_form.car.clone()), syms)?),
+ }
+ } else {
+ Err("impossible condition: args not in standard form".to_string())
+ }
+ }
+ } else {
+ Err("impossible condition: not 3 args to if".to_string())
+ }
+ } else {
+ Err("first argument to if must evaluate to be a boolean".to_string())
+ }
+ } else {
+ Err("impossible condition: not 3 args to if".to_string())
+ }
+}
+
+fn let_callback (_ast: &Seg, _syms: &mut SymTable) -> Result {
+ todo!()
+}
+
+fn while_callback (_ast: &Seg, _syms: &mut SymTable) -> Result {
+ todo!()
+}
+
+fn map_callback (_ast: &Seg, _syms: &mut SymTable) -> Result {
+ todo!()
+}
diff --git a/src/str.rs b/src/stl/str.rs
similarity index 99%
rename from src/str.rs
rename to src/stl/str.rs
index 191d4ec..418d252 100644
--- a/src/str.rs
+++ b/src/stl/str.rs
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-
+/*
use crate::func::{Args, FTable, Function, Operation};
use crate::segment::{ast_as_string, circuit, Ast, Ctr};
use crate::vars::VTable;
@@ -83,3 +83,4 @@ pub fn get_concat() -> Function {
)),
};
}
+*/
diff --git a/src/sym.rs b/src/sym.rs
index c5e087d..a5db769 100644
--- a/src/sym.rs
+++ b/src/sym.rs
@@ -39,7 +39,7 @@ pub struct UserFn {
*/
#[derive(Clone)]
pub enum ValueType {
- Internal(Rc Ctr>),
+ Internal(Rc Result>),
FuncForm(UserFn),
VarForm(Box)
}
@@ -237,7 +237,7 @@ impl Symbol {
match &self.value {
ValueType::VarForm(ref f) => Ok(Box::new(*f.clone())),
- ValueType::Internal(ref f) => Ok(Box::new(f(evaluated_args, syms))),
+ ValueType::Internal(ref f) => Ok(Box::new(f(evaluated_args, syms)?)),
ValueType::FuncForm(ref f) => {
// stores any value overwritten by local state
// If this ever becomes ASYNC this will need to
diff --git a/tests/stl.rs b/tests/stl.rs
deleted file mode 100644
index b9b4188..0000000
--- a/tests/stl.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-/* relish: versatile lisp shell
- * Copyright (C) 2021 Aidan Hahn
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-use crate::append::get_append;
-use crate::func::{func_declare, FTable};
-use crate::segment::Ctr;
-use crate::str::{get_concat, get_echo};
-use crate::control::{get_if};
-use crate::vars::{get_export, VTable};
-use std::cell::RefCell;
-use std::rc::Rc;
-
-pub fn get_stdlib(conf: Rc>) -> Result>, String> {
- let ft = Rc::new(RefCell::new(FTable::new()));
- if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_echo()))) {
- return Err(s);
- }
- if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_append()))) {
- return Err(s);
- }
- if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_concat()))) {
- return Err(s);
- }
-
- let mut cfg_env = true;
- match conf.borrow().get(&String::from("CFG_RELISH_ENV")) {
- None => {
- println!("CFG_RELISH_ENV not defined. defaulting to ON.")
- }
- Some(ctr) => match (**ctr).clone() {
- Ctr::String(ref s) => cfg_env = s.eq("0"),
- _ => {
- println!("Invalid value for CFG_RELISH_ENV. must be a string (0 or 1).");
- println!("Defaulting CFG_RELISH_ENV to ON");
- }
- },
- }
-
- if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_export(cfg_env)))) {
- return Err(s);
- }
-
- if let Some(s) = func_declare(ft.clone(), Rc::new(RefCell::new(get_if()))) {
- return Err(s);
- }
-
- return Ok(ft);
-}
diff --git a/tests/test_func.rs b/tests/test_func.rs
index 28a7027..54e9ed2 100644
--- a/tests/test_func.rs
+++ b/tests/test_func.rs
@@ -1,4 +1,5 @@
mod func_tests {
+ use std::rc::Rc;
use relish::ast::lex;
use relish::ast::{SymTable, Type, UserFn};
use relish::ast::{Args, Symbol, Ctr, Seg, ValueType};
@@ -10,14 +11,14 @@ mod func_tests {
name: String::from("test_func_in"),
conditional_branches: false,
args: Args::Strict(vec![Type::Bool]),
- value: ValueType::Internal(Box::new(
- |a: &Seg, _: &mut SymTable| -> Ctr {
+ value: ValueType::Internal(Rc::new(
+ |a: &Seg, _: &mut SymTable| -> Result {
let inner = a;
let mut is_bool = false;
if let Ctr::Bool(_) = *inner.car {
is_bool = true;
}
- Ctr::Bool(is_bool)
+ Ok(Ctr::Bool(is_bool))
},
)),
};
@@ -123,17 +124,17 @@ mod func_tests {
name: String::from("test_inner"),
conditional_branches: false,
args: Args::Strict(vec![Type::Bool]),
- value: ValueType::Internal(Box::new(
- |a: &Seg, _: &mut SymTable| -> Ctr {
+ value: ValueType::Internal(Rc::new(
+ |a: &Seg, _: &mut SymTable| -> Result {
let inner = a;
if let Ctr::Bool(b) = *inner.car {
if b {
- Ctr::String("test".to_string())
+ Ok(Ctr::String("test".to_string()))
} else {
- Ctr::None
+ Ok(Ctr::None)
}
} else {
- Ctr::None
+ Err("not a bool".to_string())
}
},
)),
@@ -184,14 +185,14 @@ mod func_tests {
name: String::from("test_func_in"),
conditional_branches: false,
args: Args::Strict(vec![Type::Bool]),
- value: ValueType::Internal(Box::new(
- |a: &Seg, _: &mut SymTable| -> Ctr {
+ value: ValueType::Internal(Rc::new(
+ |a: &Seg, _: &mut SymTable| -> Result {
let inner = a;
let mut is_bool = false;
if let Ctr::Bool(_) = *inner.car {
is_bool = true;
}
- Ctr::Bool(is_bool)
+ Ok(Ctr::Bool(is_bool))
},
)),
};
@@ -279,14 +280,14 @@ mod func_tests {
name: String::from("test_func_in"),
conditional_branches: false,
args: Args::Strict(vec![Type::Bool]),
- value: ValueType::Internal(Box::new(
- |a: &Seg, _: &mut SymTable| -> Ctr {
+ value: ValueType::Internal(Rc::new(
+ |a: &Seg, _: &mut SymTable| -> Result {
let inner = a;
let mut is_bool = false;
if let Ctr::Bool(_) = *inner.car {
is_bool = true;
}
- Ctr::Bool(is_bool)
+ Ok(Ctr::Bool(is_bool))
},
)),
};
diff --git a/tests/test_lib_append.rs b/tests/test_lib_append.rs
index 7bcbc9c..236cffa 100644
--- a/tests/test_lib_append.rs
+++ b/tests/test_lib_append.rs
@@ -1,46 +1,22 @@
mod append_lib_tests {
- use relish::ast::{ast_to_string, eval, lex, Ctr, FTable, VTable};
- use relish::stdlib::get_stdlib;
- use std::cell::RefCell;
- use std::rc::Rc;
+ use relish::ast::{Ctr, eval, lex, SymTable};
+ use relish::stdlib::{static_stdlib, dynamic_stdlib};
#[test]
fn test_append_to_empty_list() {
- let document = "(append () 1 2 3)";
- let result = "(1 2 3)";
- let vt = Rc::new(RefCell::new(VTable::new()));
- let ft: Rc>;
- match get_stdlib(vt.clone()) {
- Ok(f) => ft = f,
- Err(s) => {
- ft = Rc::new(RefCell::new(FTable::new()));
- println!("Couldnt get stdlib: {}!", s);
- assert!(false)
+ let document = "(append () 1)";
+ let result = "(1)";
+
+ let mut syms = SymTable::new();
+ static_stdlib(&mut syms).unwrap();
+ dynamic_stdlib(false, &mut syms).unwrap();
+
+ if let Ok(tree) = lex(&document.to_string()) {
+ if let Ctr::Seg(ref s) = *eval(&tree, &mut syms).unwrap() {
+ assert_eq!(s.to_string(), result);
}
- }
-
- match lex(document.to_string()) {
- Err(s) => {
- println!("Couldnt lex {}: {}\n", document, s);
- assert!(false);
- }
-
- Ok(tree) => match eval(tree, vt.clone(), ft.clone(), false) {
- Err(s) => {
- println!("Couldnt eval {}: {}\n", document, s);
- assert!(false);
- }
-
- Ok(ctr) => match ctr {
- Ctr::Symbol(_) => assert!(false),
- Ctr::String(_) => assert!(false),
- Ctr::Integer(_) => assert!(false),
- Ctr::Float(_) => assert!(false),
- Ctr::Bool(_) => assert!(false),
- Ctr::Seg(s) => assert_eq!(ast_to_string(s), result),
- Ctr::None => assert!(false),
- },
- },
+ } else {
+ assert!(false)
}
}
@@ -48,79 +24,35 @@ mod append_lib_tests {
fn test_append_to_full_list() {
let document = "(append (1 2) 3)";
let result = "(1 2 3)";
- let vt = Rc::new(RefCell::new(VTable::new()));
- let ft: Rc>;
- match get_stdlib(vt.clone()) {
- Ok(f) => ft = f,
- Err(s) => {
- ft = Rc::new(RefCell::new(FTable::new()));
- println!("Couldnt get stdlib: {}!", s);
- assert!(false)
+
+ let mut syms = SymTable::new();
+ static_stdlib(&mut syms).unwrap();
+ dynamic_stdlib(false, &mut syms).unwrap();
+
+ if let Ok(tree) = lex(&document.to_string()) {
+ if let Ctr::Seg(ref s) = *eval(&tree, &mut syms).unwrap() {
+ assert_eq!(s.to_string(), result);
}
- }
-
- match lex(document.to_string()) {
- Err(s) => {
- println!("Couldnt lex {}: {}\n", document, s);
- assert!(false);
- }
-
- Ok(tree) => match eval(tree, vt.clone(), ft.clone(), false) {
- Err(s) => {
- println!("Couldnt eval {}: {}\n", document, s);
- assert!(false);
- }
-
- Ok(ctr) => match ctr {
- Ctr::Symbol(_) => assert!(false),
- Ctr::String(_) => assert!(false),
- Ctr::Integer(_) => assert!(false),
- Ctr::Float(_) => assert!(false),
- Ctr::Bool(_) => assert!(false),
- Ctr::Seg(s) => assert_eq!(ast_to_string(s), result),
- Ctr::None => assert!(false),
- },
- },
+ } else {
+ assert!(false);
}
}
#[test]
fn test_mono_append() {
let document = "(append)";
- let result = "()";
- let vt = Rc::new(RefCell::new(VTable::new()));
- let ft: Rc>;
- match get_stdlib(vt.clone()) {
- Ok(f) => ft = f,
- Err(s) => {
- ft = Rc::new(RefCell::new(FTable::new()));
- println!("Couldnt get stdlib: {}!", s);
- assert!(false)
+ let result = "()";
+
+ let mut syms = SymTable::new();
+ static_stdlib(&mut syms).unwrap();
+ dynamic_stdlib(false, &mut syms).unwrap();
+
+ if let Ok(tree) = lex(&document.to_string()) {
+ if let Ctr::Seg(ref s) = *eval(&tree, &mut syms).unwrap() {
+ assert_eq!(s.to_string(), result);
}
- }
-
- match lex(document.to_string()) {
- Err(s) => {
- println!("Couldnt lex {}: {}\n", document, s);
- assert!(false);
- }
-
- Ok(tree) => match eval(tree, vt.clone(), ft.clone(), false) {
- Err(s) => {
- println!("Couldnt eval {}: {}\n", document, s);
- assert!(false);
- }
-
- Ok(ctr) => match ctr {
- Ctr::Symbol(_) => assert!(false),
- Ctr::String(_) => assert!(false),
- Ctr::Integer(_) => assert!(false),
- Ctr::Float(_) => assert!(false),
- Ctr::Bool(_) => assert!(false),
- Ctr::Seg(s) => assert_eq!(ast_to_string(s), result),
- Ctr::None => assert!(false),
- },
- },
+ } else {
+ assert!(false);
}
}
@@ -128,39 +60,17 @@ mod append_lib_tests {
fn test_append_no_list() {
let document = "(append 'test' 1 2 3)";
let result = "('test' 1 2 3)";
- let vt = Rc::new(RefCell::new(VTable::new()));
- let ft: Rc>;
- match get_stdlib(vt.clone()) {
- Ok(f) => ft = f,
- Err(s) => {
- ft = Rc::new(RefCell::new(FTable::new()));
- println!("Couldnt get stdlib: {}!", s);
- assert!(false)
+
+ let mut syms = SymTable::new();
+ static_stdlib(&mut syms).unwrap();
+ dynamic_stdlib(false, &mut syms).unwrap();
+
+ if let Ok(tree) = lex(&document.to_string()) {
+ if let Ctr::Seg(ref s) = *eval(&tree, &mut syms).unwrap() {
+ assert_eq!(s.to_string(), result);
}
- }
-
- match lex(document.to_string()) {
- Err(s) => {
- println!("Couldnt lex {}: {}\n", document, s);
- assert!(false);
- }
-
- Ok(tree) => match eval(tree, vt.clone(), ft.clone(), false) {
- Err(s) => {
- println!("Couldnt eval {}: {}\n", document, s);
- assert!(false);
- }
-
- Ok(ctr) => match ctr {
- Ctr::Symbol(_) => assert!(false),
- Ctr::String(_) => assert!(false),
- Ctr::Integer(_) => assert!(false),
- Ctr::Float(_) => assert!(false),
- Ctr::Bool(_) => assert!(false),
- Ctr::Seg(s) => assert_eq!(ast_to_string(s), result),
- Ctr::None => assert!(false),
- },
- },
+ } else {
+ assert!(false);
}
}
}
diff --git a/tests/test_lib_control.rs b/tests/test_lib_control.rs
new file mode 100644
index 0000000..b6d5bb4
--- /dev/null
+++ b/tests/test_lib_control.rs
@@ -0,0 +1,64 @@
+mod control_lib_tests {
+ use relish::ast::{Ctr, eval, lex, SymTable};
+ use relish::stdlib::{static_stdlib, dynamic_stdlib};
+
+ #[test]
+ fn test_if_first_case_singlet() {
+ let document = "(if true 1 2)";
+ let result = 1;
+
+ let mut syms = SymTable::new();
+ static_stdlib(&mut syms).unwrap();
+ dynamic_stdlib(false, &mut syms).unwrap();
+
+ if let Ok(tree) = lex(&document.to_string()) {
+ if let Ctr::Integer(i) = *eval(&tree, &mut syms).unwrap() {
+ assert_eq!(i, result);
+ } else {
+ assert!(false);
+ }
+ } else {
+ assert!(false);
+ }
+ }
+
+ #[test]
+ fn test_if_second_case_singlet() {
+ let document = "(if false 1 2)";
+ let result = 2;
+
+ let mut syms = SymTable::new();
+ static_stdlib(&mut syms).unwrap();
+ dynamic_stdlib(false, &mut syms).unwrap();
+
+ if let Ok(tree) = lex(&document.to_string()) {
+ if let Ctr::Integer(i) = *eval(&tree, &mut syms).unwrap() {
+ assert_eq!(i, result);
+ } else {
+ assert!(false);
+ }
+ } else {
+ assert!(false);
+ }
+ }
+
+ #[test]
+ fn test_complex_case_call() {
+ let document = "(if true (append () 1) 2)";
+ let result = "(1)";
+
+ let mut syms = SymTable::new();
+ static_stdlib(&mut syms).unwrap();
+ dynamic_stdlib(false, &mut syms).unwrap();
+
+ if let Ok(tree) = lex(&document.to_string()) {
+ if let Ctr::Seg(ref i) = *eval(&tree, &mut syms).unwrap() {
+ assert_eq!(i.to_string(), result);
+ } else {
+ assert!(false);
+ }
+ } else {
+ assert!(false);
+ }
+ }
+}
diff --git a/tests/test_lib_str.rs b/tests/test_lib_str.rs
index 382b65e..6f45e56 100644
--- a/tests/test_lib_str.rs
+++ b/tests/test_lib_str.rs
@@ -1,4 +1,4 @@
-mod str_lib_tests {
+/*mod str_lib_tests {
use relish::ast::{eval, lex, Ctr, FTable, VTable};
use relish::stdlib::get_stdlib;
use std::cell::RefCell;
@@ -124,3 +124,4 @@ mod str_lib_tests {
}
}
}
+*/
diff --git a/tests/test_vars.rs b/tests/test_vars.rs
index 9197e01..f412c06 100644
--- a/tests/test_vars.rs
+++ b/tests/test_vars.rs
@@ -1,62 +1,35 @@
-/*mod var_lib_tests {
- use relish::ast::{eval, lex, SYM_TABLE};
- use relish::ast::{Args, Symbol, Ctr, Seg, ValueType, UserFn};
+mod var_lib_tests {
+ use relish::ast::{eval, lex, SymTable, Ctr};
+ use relish::stdlib::{static_stdlib, dynamic_stdlib};
#[test]
fn test_variable_export_and_lookup() {
let doc1 = "(export test 1)";
- let doc2 = "(concat test)";
- let result = "1";
+ let doc2 = "test";
+ let result = 1;
- match get_stdlib(vt.clone()) {
- Ok(f) => ft = f,
- Err(s) => {
- ft = Rc::new(RefCell::new(FTable::new()));
- println!("Couldnt get stdlib: {}!", s);
+ let mut syms = SymTable::new();
+ static_stdlib(&mut syms).unwrap();
+ dynamic_stdlib(false, &mut syms).unwrap();
+
+ if let Ok(tree) = lex(&doc1.to_string()) {
+ if let Ctr::None = *eval(&tree, &mut syms).unwrap() {
+ // pass
+ } else {
assert!(false);
}
+ } else {
+ assert!(false);
}
- match lex(doc1.to_string()) {
- Err(s) => {
- println!("Couldnt lex {}: {}", doc1, s);
+ if let Ok(tree) = lex(&doc2.to_string()) {
+ if let Ctr::Integer(i) = *eval(&tree, &mut syms).unwrap() {
+ assert_eq!(i, result);
+ } else {
assert!(false);
}
-
- Ok(tree) => match eval(tree, vt.clone(), ft.clone(), false) {
- Err(s) => {
- println!("Couldnt eval {}: {}", doc2, s);
- assert!(false);
- }
-
- Ok(ctr) => {
- println!("{:#?}", vt);
- match ctr {
- Ctr::None => assert!(true),
- _ => assert!(false),
- }
- }
- },
- }
-
- match lex(doc2.to_string()) {
- Err(s) => {
- println!("Couldnt lex {}: {}", doc2, s);
- assert!(false);
- }
-
- Ok(tree) => match eval(tree, vt.clone(), ft.clone(), false) {
- Err(s) => {
- println!("Couldnt eval {}: {}", doc2, s);
- assert!(false);
- }
-
- Ok(ctr) => match ctr {
- Ctr::String(s) => assert_eq!(s, result),
- _ => assert!(false),
- },
- },
+ } else {
+ assert!(false);
}
}
}
-*/