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> = LazyLock::new(|| Arc::new(Value::Identifier("T".into()))); pub static F: LazyLock> = LazyLock::new(|| Arc::new(Value::Identifier("F".into()))); pub static NIL: LazyLock> = LazyLock::new(|| Arc::new(Value::Identifier("NIL".into()))); fn delsh_bool(value: bool) -> Arc { match value { true => T.clone(), false => NIL.clone(), } } pub fn quote(_interpreter: &mut Interpreter, args: &[Arc]) -> Arc { args[0].clone() } pub fn eval(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { 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]) -> Arc { 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::>(); 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]) -> Arc { 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]) -> Arc { 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]) -> Arc { 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]) -> Arc { 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]) -> Arc { 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]) -> Arc { 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]) -> Arc { 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]) -> Arc { 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]) -> Arc { let expression = args[0].clone(); loop { interpreter.eval(expression.clone()); } } pub fn cons(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { Arc::new(Value::Pair( interpreter.eval(args[0].clone()), interpreter.eval(args[1].clone()), )) } pub fn ff(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { fn ff_inner(arg: Arc) -> Arc { 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]) -> Arc { fn subst_inner(replacement: Arc, pattern: Arc, full: Arc) -> Arc { 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]) -> Arc { 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]) -> Arc { let x = interpreter.eval(args[0].clone()); delsh_bool(x == *NIL) } pub fn maplist(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { 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::>(); interpreter::vec_to_value(&mapped) } pub fn and(interpreter: &mut Interpreter, args: &[Arc]) -> Arc { 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]) -> Arc { 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]) -> Arc { is_nil(interpreter, args) }