From 35a081162f1e784f1078bf8daa79e4fbf88720c2 Mon Sep 17 00:00:00 2001 From: Lawrence Bethlenfalvy Date: Sun, 5 Mar 2023 19:57:06 +0000 Subject: [PATCH] Last working state --- src/external/numbers/mod.rs | 54 ++++++----- src/foreign_macros.rs | 186 ------------------------------------ 2 files changed, 30 insertions(+), 210 deletions(-) diff --git a/src/external/numbers/mod.rs b/src/external/numbers/mod.rs index cfe6b6c..07627cd 100644 --- a/src/external/numbers/mod.rs +++ b/src/external/numbers/mod.rs @@ -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()) }); \ No newline at end of file diff --git a/src/foreign_macros.rs b/src/foreign_macros.rs index 963349a..647d2da 100644 --- a/src/foreign_macros.rs +++ b/src/foreign_macros.rs @@ -144,190 +144,4 @@ 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 - ); - }; } \ No newline at end of file