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::rc::Rc;
|
||||||
use std::hash::Hash;
|
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::foreign::{ExternError, ExternFn, Atom, Atomic};
|
||||||
use crate::representations::Primitive;
|
use crate::representations::Primitive;
|
||||||
use crate::representations::interpreted::{Clause, InternalError};
|
use crate::representations::interpreted::{Clause, InternalError};
|
||||||
|
|
||||||
// xfn_initial!(
|
/// Multiply function
|
||||||
// /// Multiply function
|
///
|
||||||
// Multiply2, Multiply1
|
/// Next state: [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())
|
|
||||||
// );
|
|
||||||
|
|
||||||
xfn!((
|
#[derive(Clone)]
|
||||||
/// Multiply function
|
pub struct Multiply2;
|
||||||
a: Numeric: |c: &Clause| c.clone().try_into(),
|
externfn_impl!(Multiply2, |_: &Self, c: Clause| {Ok(Multiply1{c})});
|
||||||
/// Partially applied multiply function
|
|
||||||
b: Numeric: |c: &Clause| c.clone().try_into()
|
/// 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())
|
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