Added USERLIB with prepend and set.
Added a q shortcut to quote get-doc and set-doc no longer conditionally evaluate args Fixed bug in let, documented potential performance improvements upped default history to 5k lines
This commit is contained in:
parent
a01df6b7b2
commit
1ee9ba55fb
7 changed files with 70 additions and 25 deletions
|
|
@ -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.
|
||||
|
|
|
|||
30
snippets/userlib.rls
Normal file
30
snippets/userlib.rls
Normal file
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
;;
|
||||
;; 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)))
|
||||
|
|
@ -78,7 +78,7 @@ fn main() -> ! {
|
|||
let mut rl = Reedline::create();
|
||||
let maybe_hist: Box<FileBackedHistory>;
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
19
src/stl.rs
19
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)),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -205,8 +205,13 @@ pub fn let_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
|
||||
// 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(),
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ pub fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
}
|
||||
},
|
||||
_ => 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<Ctr, String> {
|
||||
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<Ctr, String> {
|
||||
if ast.len() != 2 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue