1use alloc::collections::VecDeque;
2
3use alloc::vec;
4use alloc::vec::Vec;
5
6use crate::{Builtin, Instruction, Memory, Scope, Type, Value};
7
8pub trait OperationReflect: Sized {
10 type OpCode;
12
13 fn op_code(&self) -> Self::OpCode;
15 fn args(&self) -> Option<Vec<Value>> {
18 None
19 }
20 fn args_mut(&mut self) -> Option<Vec<&mut Value>> {
21 None
22 }
23 #[allow(unused)]
26 fn from_code_and_args(op_code: Self::OpCode, args: &[Value]) -> Option<Self> {
27 None
28 }
29 fn sanitize_args(&mut self, scope: &Scope);
31 fn is_commutative(&self) -> bool {
34 false
35 }
36 fn is_pure(&self) -> bool {
39 false
40 }
41
42 fn read_pointers(&self) -> Vec<Value> {
43 Vec::new()
44 }
45
46 fn write_pointers(&self) -> Vec<Value> {
47 Vec::new()
48 }
49}
50
51pub trait OperationArgs: Sized {
53 fn sanitize_args_ptr(&mut self, scope: &Scope);
57
58 #[allow(unused)]
61 fn from_args(args: &[Value]) -> Option<Self> {
62 None
63 }
64
65 fn as_args(&self) -> Option<Vec<Value>> {
68 None
69 }
70
71 fn as_args_mut(&mut self) -> Option<Vec<&mut Value>> {
74 None
75 }
76
77 fn read_pointers(&self) -> Vec<Value> {
78 Vec::new()
79 }
80
81 fn write_pointers(&self) -> Vec<Value> {
82 Vec::new()
83 }
84}
85
86impl OperationArgs for Value {
87 fn sanitize_args_ptr(&mut self, scope: &Scope) {
88 *self = read_value(scope, *self)
89 }
90
91 fn from_args(args: &[Value]) -> Option<Self> {
92 Some(args[0])
93 }
94
95 fn as_args(&self) -> Option<Vec<Value>> {
96 Some(vec![*self])
97 }
98
99 fn as_args_mut(&mut self) -> Option<Vec<&mut Value>> {
100 Some(vec![self])
101 }
102}
103
104impl<T: OperationArgs> OperationArgs for Vec<T> {
105 fn sanitize_args_ptr(&mut self, scope: &Scope) {
106 self.iter_mut().for_each(|it| it.sanitize_args_ptr(scope));
107 }
108
109 fn as_args_mut(&mut self) -> Option<Vec<&mut Value>> {
110 let inner = self.iter_mut().map(|it| it.as_args_mut());
111 let inner = inner.collect::<Option<Vec<_>>>()?;
112 Some(inner.into_iter().flatten().collect())
113 }
114}
115
116impl<T: OperationArgs> OperationArgs for Option<T> {
117 fn sanitize_args_ptr(&mut self, scope: &Scope) {
118 if let Some(it) = self.as_mut() {
119 it.sanitize_args_ptr(scope)
120 }
121 }
122
123 fn as_args_mut(&mut self) -> Option<Vec<&mut Value>> {
124 self.as_mut().and_then(|inner| inner.as_args_mut())
125 }
126}
127
128impl OperationArgs for usize {
129 fn sanitize_args_ptr(&mut self, _: &Scope) {}
130
131 fn from_args(args: &[Value]) -> Option<Self> {
132 Some(args[0].as_const().unwrap().as_usize())
133 }
134 fn as_args(&self) -> Option<Vec<Value>> {
135 Some(vec![(*self).into()])
136 }
137 fn as_args_mut(&mut self) -> Option<Vec<&mut Value>> {
138 Some(vec![])
139 }
140}
141impl OperationArgs for u32 {
142 fn sanitize_args_ptr(&mut self, _: &Scope) {}
143
144 fn from_args(args: &[Value]) -> Option<Self> {
145 Some(args[0].as_const().unwrap().as_u32())
146 }
147 fn as_args(&self) -> Option<Vec<Value>> {
148 Some(vec![(*self).into()])
149 }
150 fn as_args_mut(&mut self) -> Option<Vec<&mut Value>> {
151 Some(vec![])
152 }
153}
154impl OperationArgs for bool {
155 fn sanitize_args_ptr(&mut self, _: &Scope) {}
156
157 fn from_args(args: &[Value]) -> Option<Self> {
158 Some(args[0].as_const().unwrap().as_bool())
159 }
160 fn as_args(&self) -> Option<Vec<Value>> {
161 Some(vec![(*self).into()])
162 }
163 fn as_args_mut(&mut self) -> Option<Vec<&mut Value>> {
164 Some(vec![])
165 }
166}
167
168pub trait FromArgList: Sized {
170 fn from_arg_list(args: &mut VecDeque<Value>) -> Self;
173 fn as_arg_list(&self) -> impl IntoIterator<Item = Value>;
175 fn as_arg_list_mut(&mut self) -> impl IntoIterator<Item = &mut Value>;
176}
177
178impl FromArgList for Value {
179 fn from_arg_list(args: &mut VecDeque<Value>) -> Self {
180 args.pop_front().expect("Missing value from arg list")
181 }
182
183 fn as_arg_list(&self) -> impl IntoIterator<Item = Value> {
184 [*self]
185 }
186
187 fn as_arg_list_mut(&mut self) -> impl IntoIterator<Item = &mut Value> {
188 [self]
189 }
190}
191
192impl FromArgList for Vec<Value> {
193 fn from_arg_list(args: &mut VecDeque<Value>) -> Self {
194 core::mem::take(args).into_iter().collect()
195 }
196
197 fn as_arg_list(&self) -> impl IntoIterator<Item = Value> {
198 self.iter().cloned()
199 }
200
201 fn as_arg_list_mut(&mut self) -> impl IntoIterator<Item = &mut Value> {
202 self.iter_mut()
203 }
204}
205
206impl FromArgList for bool {
207 fn from_arg_list(args: &mut VecDeque<Value>) -> Self {
208 args.pop_front()
209 .expect("Missing value from arg list")
210 .as_const()
211 .unwrap()
212 .as_bool()
213 }
214
215 fn as_arg_list(&self) -> impl IntoIterator<Item = Value> {
216 [(*self).into()]
217 }
218
219 fn as_arg_list_mut(&mut self) -> impl IntoIterator<Item = &mut Value> {
220 []
221 }
222}
223
224impl FromArgList for u32 {
225 fn from_arg_list(args: &mut VecDeque<Value>) -> Self {
226 args.pop_front()
227 .expect("Missing value from arg list")
228 .as_const()
229 .unwrap()
230 .as_u32()
231 }
232
233 fn as_arg_list(&self) -> impl IntoIterator<Item = Value> {
234 [(*self).into()]
235 }
236
237 fn as_arg_list_mut(&mut self) -> impl IntoIterator<Item = &mut Value> {
238 []
239 }
240}
241
242impl OperationArgs for Builtin {
243 fn sanitize_args_ptr(&mut self, _: &crate::Scope) {}
244}
245
246impl FromArgList for usize {
247 fn from_arg_list(args: &mut VecDeque<Value>) -> Self {
248 args.pop_front()
249 .expect("Missing value from arg list")
250 .as_const()
251 .unwrap()
252 .as_usize()
253 }
254
255 fn as_arg_list(&self) -> impl IntoIterator<Item = Value> {
256 [(*self).into()]
257 }
258
259 fn as_arg_list_mut(&mut self) -> impl IntoIterator<Item = &mut Value> {
260 []
261 }
262}
263
264fn read_value(scope: &Scope, val: Value) -> Value {
265 if let Type::Pointer(inner, _) = val.ty {
266 let out = scope.create_value(*inner);
267 scope.register(Instruction::new(Memory::Load(val), out));
268 out
269 } else {
270 val
271 }
272}