use std::sync::{Arc, LazyLock};
use crate::interpreter::{self, Interpreter, Value, wrap_in_quote};
mod lists;
mod numbers;
mod pairlists;
pub use lists::*;
pub use numbers::*;
pub use pairlists::*;
pub static T: LazyLock<Arc<Value>> = LazyLock::new(|| Arc::new(Value::Identifier("T".into())));
pub static F: LazyLock<Arc<Value>> = LazyLock::new(|| Arc::new(Value::Identifier("F".into())));
pub static NIL: LazyLock<Arc<Value>> = LazyLock::new(|| Arc::new(Value::Identifier("NIL".into())));
fn delsh_bool(value: bool) -> Arc<Value> {
match value {
true => T.clone(),
false => NIL.clone(),
}
}
pub fn quote(_interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
args[0].clone()
}
pub fn eval(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let form = interpreter.eval(args[0].clone());
let variables = args
.get(1)
.map(|value| interpreter.eval(value.clone()).list().expect("a pair list"));
interpreter.push_frame();
if let Some(variables) = variables {
for variable in variables {
let Some((name, value)) = variable.pair() else {
continue;
};
let Some(name) = name.string() else {
continue;
};
interpreter.set_atom(name.clone(), value.clone());
}
}
let result = interpreter.eval(form);
interpreter.pop_frame();
result
}
pub fn apply(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let function = interpreter.eval(args[0].clone());
let arguments = interpreter
.eval(args[1].clone())
.list()
.expect("a list of arguments")
.into_iter()
.map(wrap_in_quote)
.collect::<Box<_>>();
let variables = args.get(2).map(|value| {
interpreter
.eval(value.clone())
.list()
.expect("a list of variables")
});
interpreter.push_frame();
if let Some(variables) = variables {
for variable in variables {
let Some((name, value)) = variable.pair() else {
continue;
};
let Some(name) = name.string() else {
continue;
};
interpreter.set_atom(name.clone(), value.clone());
}
}
let result = interpreter.run_function(&function, &arguments);
interpreter.pop_frame();
result
}
pub fn define(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let definitions = args[0].list().expect("a list of definitions");
for definition in definitions {
let pair = definition.list().expect("a name-value pair");
let Some(name) = pair[0].string() else {
continue;
};
let value = interpreter.eval(pair[1].clone());
interpreter.set_atom(name.clone(), value);
}
NIL.clone()
}
pub fn set(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let lhs = args[0]
.identifier()
.expect("an identifier on the left side");
let rhs = interpreter.eval(args[1].clone());
interpreter.set_atom(lhs.clone(), rhs.clone());
rhs
}
pub fn lambda(_interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
Arc::new(Value::DelshFn {
args: args[0]
.list()
.expect("a list of argument names")
.into_iter()
.filter_map(|value| value.identifier().cloned())
.collect(),
command: args[1].clone(),
})
}
pub fn defun(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let Value::Identifier(function_name) = &*args[0] else {
return NIL.clone();
};
let function = Value::DelshFn {
args: args[1]
.list()
.expect("a list of parameter names")
.into_iter()
.filter_map(|value| value.identifier().cloned())
.collect(),
command: args[2].clone(),
};
let function = Arc::new(function);
interpreter.set_atom(function_name.clone(), function.clone());
function
}
pub fn do_function(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let Some(last_arg) = args.last() else {
return NIL.clone();
};
for arg in &args[..args.len() - 1] {
interpreter.eval(arg.clone());
}
interpreter.eval(last_arg.clone())
}
pub fn if_function(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let condition = interpreter.eval(args[0].clone());
let if_block = args[1].clone();
let else_block = args[2].clone();
if condition != *NIL {
interpreter.eval(if_block)
} else {
interpreter.eval(else_block)
}
}
pub fn cond_function(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
for case in args {
let case = case.list().expect("a list of cases");
let condition = interpreter.eval(case[0].clone());
if condition != *NIL {
let mut result = NIL.clone();
for command in &case[1..] {
result = interpreter.eval(command.clone());
}
return result;
}
}
NIL.clone()
}
pub fn while_function(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let condition = args[0].clone();
let while_block = args[1].clone();
while interpreter.eval(condition.clone()) != NIL.clone() {
interpreter.eval(while_block.clone());
}
NIL.clone()
}
pub fn loop_function(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let expression = args[0].clone();
loop {
interpreter.eval(expression.clone());
}
}
pub fn cons(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
Arc::new(Value::Pair(
interpreter.eval(args[0].clone()),
interpreter.eval(args[1].clone()),
))
}
pub fn ff(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
fn ff_inner(arg: Arc<Value>) -> Arc<Value> {
if let Value::Pair(a, _b) = &*arg {
ff_inner(a.clone())
} else {
arg
}
}
ff_inner(interpreter.eval(args[0].clone()))
}
pub fn subst(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
fn subst_inner(replacement: Arc<Value>, pattern: Arc<Value>, full: Arc<Value>) -> Arc<Value> {
if full == pattern {
return replacement;
}
if let Value::Pair(a, b) = &*full {
return Arc::new(Value::Pair(
subst_inner(replacement.clone(), pattern.clone(), a.clone()),
subst_inner(replacement, pattern, b.clone()),
));
}
full
}
let arg1 = interpreter.eval(args[0].clone());
let arg2 = interpreter.eval(args[1].clone());
let arg3 = interpreter.eval(args[2].clone());
subst_inner(arg1, arg2, arg3)
}
pub fn is_atom(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
match &*interpreter.eval(args[0].clone()) {
Value::Identifier(_) => T.clone(),
Value::Number(_) => T.clone(),
Value::String(_) => T.clone(),
Value::RustFn(_) => T.clone(),
Value::DelshFn { .. } => T.clone(),
Value::Pair(..) => NIL.clone(),
}
}
pub fn is_nil(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let x = interpreter.eval(args[0].clone());
delsh_bool(x == *NIL)
}
pub fn maplist(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
let list = interpreter.eval(args[0].clone()).list().expect("a list");
let mapper = interpreter.eval(args[1].clone());
let mapped = list
.into_iter()
.map(|i| interpreter.run_function(&mapper, &[i]))
.collect::<Box<_>>();
interpreter::vec_to_value(&mapped)
}
pub fn and(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
for arg in args {
let arg = interpreter.eval(arg.clone());
if arg != *NIL {
return arg;
}
}
NIL.clone()
}
pub fn or(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
for arg in args {
let arg = interpreter.eval(arg.clone());
if arg == *NIL {
return arg;
}
}
NIL.clone()
}
pub fn not(interpreter: &mut Interpreter, args: &[Arc<Value>]) -> Arc<Value> {
is_nil(interpreter, args)
}
|