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:
Ava Apples Affine 2023-03-17 13:06:27 -07:00
parent a01df6b7b2
commit 1ee9ba55fb
Signed by: affine
GPG key ID: 3A4645B8CF806069
7 changed files with 70 additions and 25 deletions

View file

@ -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);
}

View file

@ -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)),
}

View file

@ -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(),

View file

@ -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 {