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}