better eval and test for eval,quote
This commit is contained in:
parent
6daf0867df
commit
640a53cad8
4 changed files with 72 additions and 8 deletions
22
src/stl.rs
22
src/stl.rs
|
|
@ -470,6 +470,28 @@ pub fn static_stdlib(syms: &mut SymTable) -> Result<(), String> {
|
|||
},
|
||||
);
|
||||
|
||||
syms.insert(
|
||||
"quote".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 {
|
||||
name: String::from("eval"),
|
||||
args: Args::Lazy(1),
|
||||
conditional_branches: true,
|
||||
docs: decl::EVAL_DOCSTRING.to_string(),
|
||||
value: ValueType::Internal(Rc::new(decl::eval_callback)),
|
||||
},
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,17 +26,31 @@ pub fn quote_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, String> {
|
|||
if ast.len() > 1 {
|
||||
Err("do not quote more than one thing at a time".to_string())
|
||||
} else {
|
||||
Ok(Ctr::Seg(ast.clone()))
|
||||
Ok(*ast.car.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub const EVAL_DOCSTRING: &str = "takes an unevaluated argument and evaluates it.";
|
||||
pub const EVAL_DOCSTRING: &str = "takes an unevaluated argument and evaluates it.
|
||||
Specifically, does one pass of the tree simplification algorithm.
|
||||
If you have a variable referencing another variable you will get the
|
||||
referenced variable.";
|
||||
|
||||
pub fn eval_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
|
||||
if ast.len() > 1 {
|
||||
Err("do not quote more than one thing at a time".to_string())
|
||||
Err("do not eval more than one thing at a time".to_string())
|
||||
} else {
|
||||
Ok(*eval(ast, syms)?.clone())
|
||||
match *ast.car {
|
||||
Ctr::Seg(ref s) => Ok(*eval(s, syms)?.clone()),
|
||||
Ctr::Symbol(ref sym) => {
|
||||
let intermediate = syms.call_symbol(sym, &Seg::new(), true)?;
|
||||
if let Ctr::Seg(ref s) = *intermediate {
|
||||
Ok(*eval(s, syms)?.clone())
|
||||
} else {
|
||||
Ok(*intermediate)
|
||||
}
|
||||
},
|
||||
_ => Ok(*ast.car.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue