use serde::*;
use crate::{Purity, SubSide, Subscript, algorithm::ga};
macro_rules! impl_primitive {
($(
$(#[$attr:meta])*
(
$($args:literal)?
$(($outputs:expr))?
$([$margs:expr])?,
$variant:ident $(($($inner:ty),* $(,)?))?
$(, $purity:ident)?
$(,{ga: $ga:literal})?
)
),* $(,)?) => {
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum ImplPrimitive {
$(
$(#[$attr])*
$variant $(($($inner),*))?,
)*
UndoDeshape(Option<i32>),
EachSub(i32),
RowsSub(Subscript<i32>, bool),
UndoRowsSub(Subscript<i32>, bool),
UndoTransposeN(usize, i32),
UndoReverse { n: usize, all: bool },
UndoRotate(usize),
ReduceDepth(usize),
StackN { n: usize, inverse: bool },
OnSub(usize),
BySub(usize),
WithSub(usize),
OffSub(usize),
SidedFill(SubSide),
SidedEncodeBytes(SubSide),
DecodeBytes(Option<SubSide>),
MaxRowCount(usize),
BothImpl(Subscript<u32>),
UnBothImpl(Subscript<u32>),
Ga(ga::GaOp, ga::Spec),
}
impl ImplPrimitive {
pub fn args(&self) -> Option<usize> {
Some(match self {
$($(ImplPrimitive::$variant { .. } => $args,)?)*
ImplPrimitive::UndoDeshape(_) => 2,
ImplPrimitive::UndoTransposeN(n, _) => *n,
ImplPrimitive::UndoReverse { n, .. } => *n,
ImplPrimitive::UndoRotate(n) => *n + 1,
ImplPrimitive::ReduceDepth(_) => 1,
ImplPrimitive::StackN { n, .. } => *n,
ImplPrimitive::MaxRowCount(n) => *n,
ImplPrimitive::SidedEncodeBytes(_) | ImplPrimitive::DecodeBytes(_) => 2,
ImplPrimitive::Ga(op, _) => op.args(),
ImplPrimitive::MultiJoin(n) => *n,
_ => return None
})
}
pub fn outputs(&self) -> Option<usize> {
Some(match self {
$($(ImplPrimitive::$variant { .. } => $outputs,)?)*
ImplPrimitive::UndoTransposeN(n, _) => *n,
ImplPrimitive::UndoReverse { n, .. } => *n,
ImplPrimitive::UndoRotate(n) => *n,
ImplPrimitive::StackN { n, .. } => *n,
ImplPrimitive::MaxRowCount(n) => *n + 1,
ImplPrimitive::SidedEncodeBytes(_) | ImplPrimitive::DecodeBytes(_) => 1,
ImplPrimitive::Ga(op, _) => op.outputs(),
_ if self.modifier_args().is_some() => return None,
_ => 1
})
}
pub fn modifier_args(&self) -> Option<usize> {
match self {
$($(ImplPrimitive::$variant { .. } => Some($margs),)?)*
ImplPrimitive::ReduceDepth(_)
| ImplPrimitive::EachSub(_)
| ImplPrimitive::RowsSub(..) => Some(1),
ImplPrimitive::OnSub(_)
| ImplPrimitive::BySub(_)
| ImplPrimitive::WithSub(_)
| ImplPrimitive::OffSub(_)
| ImplPrimitive::BothImpl(_)
| ImplPrimitive::UnBothImpl(_) => Some(1),
ImplPrimitive::SidedFill(_) => Some(2),
_ => None
}
}
pub fn purity(&self) -> Purity {
match self {
$($(ImplPrimitive::$variant => {Purity::$purity},)*)*
ImplPrimitive::StackN { .. } => Purity::Mutating,
_ => Purity::Pure
}
}
}
};
}
impl_primitive!(
(2, Root),
(1, Cos),
(1, Asin),
(1, Acos),
(1, Ln),
(0, UnPop, Impure),
(1, UnBits),
(1, UnWhere),
(1(2), UnCouple),
(1(2), UnAdd),
(1(2), UnMul),
(1(2), UnDiv),
(1(2), UnAtan),
(1(2), UnComplex),
(1, UnUtf8),
(1, UnUtf16),
(1, UnGraphemes),
(1, UnParse),
(1, UnParseSub(usize)),
(1, UnFix),
(1, UnShape),
(1[1], UnScan),
(1(2), UnMap),
(0(0), UnStack, Impure),
(0(0)[1], UnDump, Impure),
(0[2], UnFill),
(1, Primes),
(1, UnBox),
(2, AntiDrop),
(2, AntiSelect),
(2, AntiPick),
(2, AntiKeep),
(2, AntiRotate),
(1(2), UnJoin),
(1(2), UnJoinEnd),
(2(2), UnJoinShape),
(2(2), UnJoinShapeEnd),
(3(2), UnJoinShape2),
(3(2), UnJoinShape2End),
(1(2), UnKeep),
(1(2), UnTake),
(1(2)[1], UnGroup),
(1(2)[1], UnPartition),
(1, UnSort, Impure),
(1, UnHsv),
(1, UnJson),
(1, UnJson5),
(1, UnBinary),
(1(2), UnCompress),
(2, AntiCompress),
(1, UnCsv),
(1, UnXlsx),
(1, UnFft),
(1, UnDatetime),
(2(0), MatchPattern),
(2, MatchLe),
(2, MatchGe),
(1(2), ImageDecode),
(1(2), GifDecode),
(1(3), AudioDecode),
(0, UnRawMode, Impure),
(0, UnChangeDirectory, Impure),
(1(0), UnClip, Mutating),
(1, UndoFix),
(2, UndoShape),
(2, UndoUnBits),
(2, AntiBase),
(3, UndoSelect),
(3, UndoPick),
(3, UndoTake),
(3, UndoDrop),
(2, UndoFirst),
(2, UndoLast),
(3, UndoKeep),
(3, UndoRerank),
(2, UndoReshape),
(2, UndoWindows(bool)),
(2, UndoWhere),
(2, AntiOrient),
(3, UndoAntiOrient),
(2(2), DoRegex),
(4, UndoRegex),
(3(2), UndoJoin),
(2(1)[1], UndoPartition1),
(3, UndoPartition2),
(2(1)[1], UndoGroup1),
(3, UndoGroup2),
(3, UndoGet),
(4, UndoInsert),
(3, UndoRemove),
(1(0), TryClose),
([2], UnBracket),
([1], UndoRows),
([1], UndoInventory),
(2, SetSign),
(1, FirstMinIndex),
(1, FirstMaxIndex),
(1, LastMinIndex),
(1, LastMaxIndex),
(1, FirstWhere),
(1, LastWhere),
(1, LenWhere),
(2, MemberOfRange),
(2, MultidimMemberOfRange),
(1, RandomRow, Impure),
(1, SortDown),
(1, AllSame),
(1, OneUnique),
(1, SortedUp),
(1, FirstSort),
(1, LastSort),
(1[1], ReduceContent),
([1], ReduceConjoinInventory),
(2(1)[2], ReduceTable),
(1, ReplaceRand, Impure),
(2, ReplaceRand2, Impure),
(1, CountUnique),
((2)[3], Astar),
((2)[3], AstarFirst),
((2)[3], AstarSignLen),
((1)[3], AstarPop),
((1)[3], AstarTake),
((2)[2], PathFirst),
((2)[3], PathSignLen),
((1)[2], PathPop),
((1)[2], PathTake),
(2[1], SplitByScalar),
(2[1], SplitBy),
(2[1], SplitByKeepEmpty),
(2, AbsComplex),
(1, SquareAbs),
(2, MatrixDiv),
(1, RangeSub(i32)),
(1, Exp2),
(1, Exp10),
(1, Log2),
(1, Log10),
(2(3), Over),
([1], DipN(usize)),
(1, NBits(usize)),
(1, DeshapeSub(i32)),
([1], TableSub(i32)),
([2], FoldWhile),
(1, ClassifySub(usize)),
(1, ParseSub(usize)),
(1, TransposeN(i32)),
(2, MultiKeep(usize)),
(2, SidedJoin(SubSide)),
([1], SidedStencil(SubSide)),
((1), MultiJoin(usize)),
(1, Json5),
(1, Utf16),
(1, Retropose),
([1], FixMatchRanks),
([2], RepeatWithInverse),
([1], RepeatCountConvergence),
(2(1), ValidateType),
(2(0), ValidateTypeConsume),
(2(0), TestAssert, Impure),
(1, ValidateNonBoxedVariant),
(2(1), ValidateVariant),
(2(1), TagVariant),
(3, LayoutArgs),
(2, VoxelsArgs),
([1], FoldGif),
);