use chinillaclvm_rs::allocator::{Allocator, NodePtr};
use chinillaclvm_rs::reduction::EvalErr;
use crate::classic::chinillaclvm::sexp::enlist;
use crate::classic::chinillaclvm_tools::node_path::NodePath;
lazy_static! {
pub static ref QUOTE_ATOM: Vec<u8> = vec![1];
pub static ref APPLY_ATOM: Vec<u8> = vec![2];
pub static ref COM_ATOM: Vec<u8> = vec![b'c', b'o', b'm'];
}
pub fn quote(allocator: &mut Allocator, sexp: NodePtr) -> Result<NodePtr, EvalErr> {
allocator
.new_atom("E_ATOM)
.and_then(|q| allocator.new_pair(q, sexp))
}
pub fn evaluate(
allocator: &mut Allocator,
prog: NodePtr,
args: NodePtr,
) -> Result<NodePtr, EvalErr> {
m! {
a <- allocator.new_atom(&APPLY_ATOM);
enlist(allocator, &[a, prog, args])
}
}
pub fn run(
allocator: &mut Allocator,
prog: NodePtr,
macro_lookup: NodePtr,
) -> Result<NodePtr, EvalErr> {
let args = NodePath::new(None).as_path();
m! {
mac <- quote(allocator, macro_lookup);
com_sexp <- allocator.new_atom(&COM_ATOM);
arg_sexp <- allocator.new_atom(args.data());
to_eval <- enlist(allocator, &[com_sexp, prog, mac]);
evaluate(allocator, to_eval, arg_sexp)
}
}
pub fn brun(allocator: &mut Allocator, prog: NodePtr, args: NodePtr) -> Result<NodePtr, EvalErr> {
m! {
quoted_prog <- quote(allocator, prog);
quoted_args <- quote(allocator, args);
evaluate(allocator, quoted_prog, quoted_args)
}
}