forked from Orchid/orchid
Last working state
This commit is contained in:
54
src/external/numbers/mod.rs
vendored
54
src/external/numbers/mod.rs
vendored
@@ -5,34 +5,40 @@ use std::fmt::Debug;
|
||||
use std::rc::Rc;
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::{atomic_impl, atomic_redirect, externfn_impl, xfn_initial, xfn_middle, xfn_last, xfn};
|
||||
use crate::{atomic_impl, atomic_redirect, externfn_impl};
|
||||
use crate::foreign::{ExternError, ExternFn, Atom, Atomic};
|
||||
use crate::representations::Primitive;
|
||||
use crate::representations::interpreted::{Clause, InternalError};
|
||||
|
||||
// xfn_initial!(
|
||||
// /// Multiply function
|
||||
// Multiply2, Multiply1
|
||||
// );
|
||||
// xfn_middle!(
|
||||
// /// Partially applied multiply function
|
||||
// Multiply2, Multiply1, Multiply0, (
|
||||
// a: Numeric: |c: &Clause| c.clone().try_into()
|
||||
// )
|
||||
// );
|
||||
// xfn_last!(
|
||||
// /// Fully applied Multiply function.
|
||||
// Multiply1, Multiply0, (
|
||||
// b: Numeric: |c: &Clause| c.clone().try_into(),
|
||||
// a: Numeric: |c: &Clause| c.clone().try_into()
|
||||
// ), Ok((*a * b).into())
|
||||
// );
|
||||
/// Multiply function
|
||||
///
|
||||
/// Next state: [Multiply1]
|
||||
|
||||
xfn!((
|
||||
/// Multiply function
|
||||
a: Numeric: |c: &Clause| c.clone().try_into(),
|
||||
/// Partially applied multiply function
|
||||
b: Numeric: |c: &Clause| c.clone().try_into()
|
||||
), {
|
||||
#[derive(Clone)]
|
||||
pub struct Multiply2;
|
||||
externfn_impl!(Multiply2, |_: &Self, c: Clause| {Ok(Multiply1{c})});
|
||||
|
||||
/// Partially applied Multiply function
|
||||
///
|
||||
/// Prev state: [Multiply2]; Next state: [Multiply0]
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct Multiply1{ c: Clause }
|
||||
atomic_redirect!(Multiply1, c);
|
||||
atomic_impl!(Multiply1);
|
||||
externfn_impl!(Multiply1, |this: &Self, c: Clause| {
|
||||
let a: Numeric = this.c.clone().try_into()?;
|
||||
Ok(Multiply0{ a, c })
|
||||
});
|
||||
|
||||
/// Fully applied Multiply function.
|
||||
///
|
||||
/// Prev state: [Multiply1]
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct Multiply0 { a: Numeric, c: Clause }
|
||||
atomic_redirect!(Multiply0, c);
|
||||
atomic_impl!(Multiply0, |Self{ a, c }: &Self| {
|
||||
let b: Numeric = c.clone().try_into()?;
|
||||
Ok((*a * b).into())
|
||||
});
|
||||
@@ -145,189 +145,3 @@ macro_rules! externfn_impl {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Define a new struct and implement [ExternFn] for it so that it combines with an argument into
|
||||
/// the struct identified by `$next` with a single field called `clause`.
|
||||
/// Also generates doc comment for the new struct
|
||||
#[macro_export]
|
||||
macro_rules! xfn_initial {
|
||||
(#[$prefix:meta] $name:ident, $next:ident) => {
|
||||
paste::paste!{
|
||||
#[$prefix]
|
||||
#[doc = "\n\nNext state: [" [<$next:camel>] "]"]
|
||||
#[derive(Clone)]
|
||||
pub struct [<$name:camel>];
|
||||
externfn_impl!([<$name:camel>], |_:&Self, clause: Clause| Ok([<$next:camel>]{ clause }));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Define a struct with a field `clause: Clause` that forwards atomic reductions to that field and
|
||||
/// then converts itself to an [ExternFn] which combines with an argument into the struct identified
|
||||
/// by `$next` with all fields copied over, `$nname` converted via `$ntransform` and the
|
||||
/// argument assigned to a field called `clause`.
|
||||
#[macro_export]
|
||||
macro_rules! xfn_middle {
|
||||
(#[$prefix:meta] $prev:ident, $name:ident, $next:ident, (
|
||||
$nname:ident : $ntype:ty
|
||||
$(, $fname:ident : $ftype:ty)*
|
||||
), $transform:expr) => {
|
||||
paste::paste!{
|
||||
#[$prefix]
|
||||
#[doc = "\n\nPrev state: [" [<$prev:camel>] "], Next state: [" [<$next:camel>] "]"]
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct [<$name:camel>] {
|
||||
clause: Clause,
|
||||
$($fname: $ftype),*
|
||||
}
|
||||
atomic_redirect!([<$name:camel>], clause);
|
||||
atomic_impl!([<$name:camel>]);
|
||||
externfn_impl!([<$name:camel>], |this: &Self, clause: Clause| {
|
||||
let $nname: $ntype = match ($transform)(&this.clause) {
|
||||
Ok(a) => a,
|
||||
Err(e) => return Err(e)
|
||||
};
|
||||
Ok([<$next:camel>]{
|
||||
clause,
|
||||
$nname,
|
||||
$($fname: this.$fname.clone()),*
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! xfn_last {
|
||||
(#[$prefix:meta] $prev:ident, $name:ident, (
|
||||
$nname:ident : $ntype:ty
|
||||
$(, $fname:ident : $ftype:ty)*
|
||||
), $transform:expr, $operation:expr) => {
|
||||
paste!{
|
||||
#[$prefix]
|
||||
#[doc = "\n\nPrev state: [" [<$prev:camel>] "]" ]
|
||||
#[derive(Debug, Clone, PartialEq, Hash)]
|
||||
pub struct [<$name:camel>] {
|
||||
clause: Clause,
|
||||
$($fname: $ftype),*
|
||||
}
|
||||
}
|
||||
atomic_redirect!([<$name:camel>], clause);
|
||||
atomic_impl!([<$name:camel>], |this: &Self| {
|
||||
let $nname: $ntype = match ($ntransform)(&this.clause) {
|
||||
Ok(a) => a,
|
||||
Err(e) => return Err(e)
|
||||
};
|
||||
$(
|
||||
let $fname = &this.$fname;
|
||||
)*
|
||||
$operation
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! reverse_proplist {
|
||||
(
|
||||
#[$nprefix:meta] $nname:ident : $ntype:ty : $ntransform:expr
|
||||
$(, #[$fprefix:meta] $fname:ident : $ftype:ty : $ftransform:expr)*
|
||||
) => {
|
||||
reverse_proplist!($($fname : $ftype : $ftransform),*)
|
||||
$nname : $ntype : $ntranform
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! xfn_make_head {
|
||||
(
|
||||
#[$cprefix:meta] $nname:ident : $ntype:ty : $ntransform:expr
|
||||
, #[$nprefix:meta] $cname:ident : $ctype:ty : $ctransform:expr
|
||||
$(, #[$fprefix:meta] $fname:ident : $ftype:ty : $ftransform:expr)+
|
||||
) => {
|
||||
xfn_make_head!(
|
||||
#[$nprefix] $cname : $ctype : $ctransform
|
||||
$(, #[$fprefix] $fname : $ftype : $ftransform)+
|
||||
)
|
||||
}; // skip through all intermediate rows
|
||||
(
|
||||
#[$cprefix:meta] $nname:ident : $ntype:ty : $ntransform:expr
|
||||
, #[$nprefix:meta] $cname:ident : $ctype:ty : $ctransform:expr
|
||||
) => {
|
||||
paste!{
|
||||
xfn_initial!(#[$cprefix] $cname, $nname)
|
||||
}
|
||||
} // process first two rows
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! xfn_make_middle {
|
||||
(
|
||||
#[$nprefix:meta] $nname:ident : $ntype:ty : $ntransform:expr
|
||||
, #[$cprefix:meta] $cname:ident : $ctype:ty : $ctransform:expr
|
||||
, #[$pprefix:meta] $pname:ident : $ptype:ty : $ptransform:expr
|
||||
$(, #[$fprefix:meta] $fname:ident : $ftype:ty : $ftransform:expr)*
|
||||
) => {
|
||||
// repeat on tail
|
||||
xfn_make_middle!(
|
||||
#[$cprefix:meta] $cname:ident : $ctype:ty : $ctransform:expr
|
||||
, #[$pprefix:meta] $pname:ident : $ptype:ty : $ptransform:expr
|
||||
$(, #[$fprefix:meta] $fname:ident : $ftype:ty : $ftransform:expr)*
|
||||
)
|
||||
xfn_middle!(#[$cprefix] $pname, $cname, $nname (
|
||||
$cname : $ctype
|
||||
, $pname : $ptype
|
||||
$(, $fname : $ftype )*
|
||||
), $ctransform) // note that the "next" row is not included
|
||||
};
|
||||
(
|
||||
#[$nprefix:meta] $nname:ident : $ntype:ty : $ntransform:expr
|
||||
, #[$cprefix:meta] $cname:ident : $ctype:ty : $ctransform:expr
|
||||
) => {}; // discard last two rows (xfn_make_head handles those)
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! xfn_make_last {
|
||||
((
|
||||
#[$cprefix:meta] $cname:ident : $ctype:ty : $ctransform:expr
|
||||
, #[$pprefix:meta] $pname:ident : $ptype:ty : $ptransform:expr
|
||||
$(, #[$fprefix:meta] $fname:ident : $ftype:ty : $ftransform:expr)*
|
||||
), $operation:expr) => {
|
||||
xfn_last!(
|
||||
#[$cprefix] $pname, $cname, (
|
||||
$cname : $ctype
|
||||
, $pname : $ptype
|
||||
$(, $fname : $ftype)*
|
||||
), $ctransform, $operation
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! xfn_reversed {
|
||||
(
|
||||
( $(#[$fprefix:meta] $fname:ident : $ftype:ty : $ftransform:expr),* ),
|
||||
$operation:expr
|
||||
) => {
|
||||
xfn_make_head!($(#[$fprefix] $fname : $ftype : $ftransform),*)
|
||||
xfn_make_middle!(
|
||||
$(#[$fprefix] $fname : $ftype : $ftransform),*
|
||||
)
|
||||
xfn_make_last(
|
||||
( $(#[$fprefix] $fname : $ftype : $ftransform),* ),
|
||||
$operation
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! xfn {
|
||||
(
|
||||
( $(#[$fprefix:meta] $fname:ident : $ftype:ty : $ftransform:expr),* ),
|
||||
$operation:expr
|
||||
) => {
|
||||
$crate::xfn_reversed!(
|
||||
reverse_proplist!($(#[$fprefix] $fname : $ftype : $ftransform),*),
|
||||
$operation
|
||||
);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user