diff --git a/Readme.org b/Readme.org
index f4060e4..e591d71 100644
--- a/Readme.org
+++ b/Readme.org
@@ -470,8 +470,6 @@ This contains any executable target of this project. Notably the main shell file
Note: this section will not show the status of each item unless you are viewing it with a proper orgmode viewer.
Note: this section only tracks the state of incomplete TODO items. Having everything on here would be cluttered.
-*** TODO Symbols defined within let by def statements must be pulled out and made global
-*** TODO Def must eval args for symbol and doc
*** TODO Shell prompt is fully configurable (L, R, and Delim)
*** TODO Load (load a script) function
Pull/Refactor the logic out of the configure functions.
diff --git a/snippets/userlib.rls b/snippets/userlib.rls
new file mode 100644
index 0000000..1e58d88
--- /dev/null
+++ b/snippets/userlib.rls
@@ -0,0 +1,30 @@
+;; 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 .
+;;
+;; USERLIB
+;; This file contains a plethora of useful features that are not shipped in the STL
+
+(def prepend
+'takes a list and appends an element to the back of it.
+ returns prepended list'
+ (elem list)
+ (reverse (append (reverse list) elem)))
+
+(def set
+'sets an existing variable without touching its docstring'
+ (var val)
+ (let ((doc (get-doc var)))
+ (def (eval var) doc val)))
\ No newline at end of file
diff --git a/src/bin/main.rs b/src/bin/main.rs
index 8a08e96..0bda1b9 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -78,7 +78,7 @@ fn main() -> ! {
let mut rl = Reedline::create();
let maybe_hist: Box;
if !hist_file_name.is_empty() {
- maybe_hist = Box::new(FileBackedHistory::with_file(5, hist_file_name.into())
+ maybe_hist = Box::new(FileBackedHistory::with_file(5000, hist_file_name.into())
.expect("error reading history!"));
rl = rl.with_history(maybe_hist);
}
diff --git a/src/stl.rs b/src/stl.rs
index 2242b89..5f5c988 100644
--- a/src/stl.rs
+++ b/src/stl.rs
@@ -481,6 +481,17 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
},
);
+ syms.insert(
+ "q".to_string(),
+ Symbol {
+ name: String::from("quote"),
+ args: Args::Lazy(1),
+ conditional_branches: true,
+ docs: decl::QUOTE_DOCSTRING.to_string(),
+ value: ValueType::Internal(Rc::new(decl::quote_callback)),
+ },
+ );
+
syms.insert(
"eval".to_string(),
Symbol {
@@ -507,8 +518,8 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
"get-doc".to_string(),
Symbol {
name: String::from("get-doc"),
- args: Args::Lazy(1),
- conditional_branches: true,
+ args: Args::Strict(vec![Type::Symbol]),
+ conditional_branches: false,
docs: decl::GETDOC_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::getdoc_callback)),
}
@@ -518,8 +529,8 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
"set-doc".to_string(),
Symbol {
name: String::from("get-doc"),
- args: Args::Lazy(2),
- conditional_branches: true,
+ args: Args::Strict(vec![Type::Symbol, Type::String]),
+ conditional_branches: false,
docs: decl::SETDOC_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(decl::setdoc_callback)),
}
diff --git a/src/stl/control.rs b/src/stl/control.rs
index 6a6509c..3ceee80 100644
--- a/src/stl/control.rs
+++ b/src/stl/control.rs
@@ -205,8 +205,13 @@ pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result {
// we need to get any var declared from within the let eval forms
// those need to exist in the outside context
+ // TODO: make this more optimal
+ // How can we skip iterations?
+ // implement a counter for number of calls to def
+ // store it inside the SymTable and Symbol
+ // only re-insert into global scope what is most recent
for i in localsyms.iter() {
- if !locals.contains(i.0) && !syms.contains_key(i.0) {
+ if !locals.contains(i.0) {
syms.insert(
i.0.clone(),
i.1.clone(),
diff --git a/src/stl/decl.rs b/src/stl/decl.rs
index 4ffa56e..506d4d2 100644
--- a/src/stl/decl.rs
+++ b/src/stl/decl.rs
@@ -69,7 +69,7 @@ pub fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result {
}
},
_ => Ok(arguments)
- }*/
+ }*/
}
}
@@ -195,27 +195,28 @@ pub fn lambda_callback(
}
pub const GETDOC_DOCSTRING: &str = "accepts an unevaluated symbol, returns the doc string.
-Returns an error if symbol is undefined";
+Returns an error if symbol is undefined.
+
+Note: make sure to quote the input like this:
+ (get-doc (quote symbol-name))";
pub fn getdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result {
- if ast.len() != 1 {
- Err("get-doc only takes a single argument".to_string())
- } else {
- if let Ctr::Symbol(ref symbol) = *ast.car {
- if let Some(sym) = syms.get(symbol) {
- Ok(Ctr::String(sym.docs.clone()))
- } else {
- Err("undefined symbol".to_string())
- }
-
+ if let Ctr::Symbol(ref symbol) = *ast.car {
+ if let Some(sym) = syms.get(symbol) {
+ Ok(Ctr::String(sym.docs.clone()))
} else {
- Err("get-doc should only be called on a symbol".to_string())
+ Err("undefined symbol".to_string())
}
+ } else {
+ Err("get-doc should only be called on a symbol".to_string())
}
}
pub const SETDOC_DOCSTRING: &str = "accepts a symbol and a doc string.
-Returns an error if symbol is undefined, otherwise sets the symbols docstring to the argument.";
+Returns an error if symbol is undefined, otherwise sets the symbols docstring to the argument.
+
+Note: make sure to quote the input like this:
+ (set-doc (quote symbol-name) my-new-docs)";
pub fn setdoc_callback(ast: &Seg, syms: &mut SymTable) -> Result {
if ast.len() != 2 {
diff --git a/tests/test_lib_decl.rs b/tests/test_lib_decl.rs
index 2e2a41d..6db5b05 100644
--- a/tests/test_lib_decl.rs
+++ b/tests/test_lib_decl.rs
@@ -112,7 +112,7 @@ mod decl_lib_tests {
let doc1 = "(def test-doc 'docs for test' 'test tests tests test')";
let doc2 = "(def test test-doc 'one')";
let doc3 = "(eq? (and
- (eq? (get-doc test) test-doc)
+ (eq? (get-doc (quote test)) test-doc)
(eq? test 'one')))";
let mut syms = SymTable::new();
@@ -337,8 +337,8 @@ mod decl_lib_tests {
#[test]
fn test_setget_doc_string() {
- let highly_inadvisable = "(set-doc help 'help')";
- let document = "(get-doc help)";
+ let highly_inadvisable = "(set-doc (q help) 'help')";
+ let document = "(get-doc (q help))";
let mut syms = SymTable::new();
static_stdlib(&mut syms).unwrap();
dynamic_stdlib(&mut syms).unwrap();