Files
orchid/src/gen/tpl.rs
Lawrence Bethlenfalvy ed0d64d52e Almost Alpha
Massive improvements across the board.

One day I'll adopt incremental commits.
2024-02-24 00:31:00 +00:00

71 lines
2.3 KiB
Rust

//! Various elemental components to build expression trees that all implement
//! [GenClause].
use super::traits::{GenClause, Generable};
use crate::foreign::atom::{Atom, AtomGenerator, Atomic};
/// Atom, Embed a Rust value. See also [AnyAtom]
#[derive(Debug, Clone)]
pub struct V<A: Atomic + Clone>(pub A);
impl<A: Atomic + Clone> GenClause for V<A> {
fn generate<T: Generable>(&self, ctx: T::Ctx<'_>, _: &impl Fn() -> T) -> T {
T::atom(ctx, Atom::new(self.0.clone()))
}
}
/// Atom, embed a Rust value of unspecified type. See also [V]
#[derive(Debug)]
pub struct AnyAtom(pub AtomGenerator);
impl GenClause for AnyAtom {
fn generate<T: Generable>(&self, ctx: T::Ctx<'_>, _: &impl Fn() -> T) -> T {
T::atom(ctx, self.0.run())
}
}
/// Const, Reference a constant from the execution environment. Unlike Orchid
/// syntax, this doesn't include lambda arguments. For that, use [P]
#[derive(Debug, Clone)]
pub struct C(pub &'static str);
impl GenClause for C {
fn generate<T: Generable>(&self, ctx: T::Ctx<'_>, _: &impl Fn() -> T) -> T {
T::constant(ctx, self.0.split("::"))
}
}
/// Apply a function to a value provided by [L]
#[derive(Debug, Clone)]
pub struct A<F: GenClause, X: GenClause>(pub F, pub X);
impl<F: GenClause, X: GenClause> GenClause for A<F, X> {
fn generate<T: Generable>(&self, ctx: T::Ctx<'_>, p: &impl Fn() -> T) -> T {
T::apply(ctx, |gen| self.0.generate(gen, p), |gen| self.1.generate(gen, p))
}
}
/// Apply a function to two arguments
pub fn a2(f: impl GenClause, x: impl GenClause, y: impl GenClause) -> impl GenClause {
A(A(f, x), y)
}
/// Lambda expression. The argument can be referenced with [P]
#[derive(Debug, Clone)]
pub struct L<B: GenClause>(pub &'static str, pub B);
impl<B: GenClause> GenClause for L<B> {
fn generate<T: Generable>(&self, ctx: T::Ctx<'_>, p: &impl Fn() -> T) -> T {
T::lambda(ctx, self.0, |gen| self.1.generate(gen, p))
}
}
/// Parameter to a lambda expression
#[derive(Debug, Clone)]
pub struct P(pub &'static str);
impl GenClause for P {
fn generate<T: Generable>(&self, ctx: T::Ctx<'_>, _: &impl Fn() -> T) -> T { T::arg(ctx, self.0) }
}
/// Slot for an Orchid value to be specified during execution
#[derive(Debug, Clone)]
pub struct Slot;
impl GenClause for Slot {
fn generate<T: Generable>(&self, _: T::Ctx<'_>, pop: &impl Fn() -> T) -> T { pop() }
}