1use alloc::collections::VecDeque;
2
3use alloc::vec;
4use alloc::vec::Vec;
5
6use crate::Variable;
7
8pub trait OperationReflect: Sized {
10    type OpCode;
12
13    fn op_code(&self) -> Self::OpCode;
15    fn args(&self) -> Option<Vec<Variable>> {
18        None
19    }
20    #[allow(unused)]
23    fn from_code_and_args(op_code: Self::OpCode, args: &[Variable]) -> Option<Self> {
24        None
25    }
26    fn is_commutative(&self) -> bool {
29        false
30    }
31    fn is_pure(&self) -> bool {
34        false
35    }
36}
37
38pub trait OperationArgs: Sized {
40    #[allow(unused)]
43    fn from_args(args: &[Variable]) -> Option<Self> {
44        None
45    }
46
47    fn as_args(&self) -> Option<Vec<Variable>> {
50        None
51    }
52}
53
54impl OperationArgs for Variable {
55    fn from_args(args: &[Variable]) -> Option<Self> {
56        Some(args[0])
57    }
58
59    fn as_args(&self) -> Option<Vec<Variable>> {
60        Some(vec![*self])
61    }
62}
63
64pub trait FromArgList: Sized {
66    fn from_arg_list(args: &mut VecDeque<Variable>) -> Self;
69    fn as_arg_list(&self) -> impl IntoIterator<Item = Variable>;
71}
72
73impl FromArgList for Variable {
74    fn from_arg_list(args: &mut VecDeque<Variable>) -> Self {
75        args.pop_front().expect("Missing variable from arg list")
76    }
77
78    fn as_arg_list(&self) -> impl IntoIterator<Item = Variable> {
79        [*self]
80    }
81}
82
83impl FromArgList for Vec<Variable> {
84    fn from_arg_list(args: &mut VecDeque<Variable>) -> Self {
85        core::mem::take(args).into_iter().collect()
86    }
87
88    fn as_arg_list(&self) -> impl IntoIterator<Item = Variable> {
89        self.iter().cloned()
90    }
91}
92
93impl FromArgList for bool {
94    fn from_arg_list(args: &mut VecDeque<Variable>) -> Self {
95        args.pop_front()
96            .expect("Missing variable from arg list")
97            .as_const()
98            .unwrap()
99            .as_bool()
100    }
101
102    fn as_arg_list(&self) -> impl IntoIterator<Item = Variable> {
103        [(*self).into()]
104    }
105}
106
107impl FromArgList for u32 {
108    fn from_arg_list(args: &mut VecDeque<Variable>) -> Self {
109        args.pop_front()
110            .expect("Missing variable from arg list")
111            .as_const()
112            .unwrap()
113            .as_u32()
114    }
115
116    fn as_arg_list(&self) -> impl IntoIterator<Item = Variable> {
117        [(*self).into()]
118    }
119}