1use std::{
2 cell::RefCell,
3 collections::{BTreeMap, BTreeSet},
4 rc::Rc,
5};
6
7use id_arena::{Arena, Id};
8
9pub struct Value<T, Y, R, D> {
10 pub id: Id<ValueDef<T, Y, R, D>>,
11 pub idx: Option<u32>,
12}
13
14impl<T, Y, R, D> Clone for Value<T, Y, R, D> {
15 fn clone(&self) -> Self {
16 Self {
17 id: self.id.clone(),
18 idx: self.idx.clone(),
19 }
20 }
21}
22
23pub enum Param<T, Y, R, D> {
24 Value(Value<T, Y, R, D>),
25 Data(Id<D>),
26 Fun(Id<Fun<T, Y, R, D>>),
27}
28impl<T, Y, R, D> Clone for Param<T, Y, R, D> {
29 fn clone(&self) -> Self {
30 match self {
31 Self::Value(arg0) => Self::Value(arg0.clone()),
32 Self::Data(arg0) => Self::Data(arg0.clone()),
33 Self::Fun(arg0) => Self::Fun(arg0.clone()),
34 }
35 }
36}
37pub struct Params<T, Y, R, D> {
38 pub values: Vec<Value<T, Y, R, D>>,
39 pub data: Vec<Id<D>>,
40 pub funs: Vec<Id<Fun<T, Y, R, D>>>,
41}
42impl<T, Y, R, D> Default for Params<T, Y, R, D> {
43 fn default() -> Self {
44 Self {
45 values: Default::default(),
46 data: Default::default(),
47 funs: Default::default(),
48 }
49 }
50}
51impl<T, Y, R, D> Clone for Params<T, Y, R, D> {
52 fn clone(&self) -> Self {
53 Self {
54 values: self.values.clone(),
55 data: self.data.clone(),
56 funs: self.funs.clone(),
57 }
58 }
59}
60impl<T, Y, R, D> FromIterator<Param<T, Y, R, D>> for Params<T, Y, R, D> {
61 fn from_iter<I: IntoIterator<Item = Param<T, Y, R, D>>>(iter: I) -> Self {
62 let mut p: Params<T, Y, R, D> = Default::default();
64 for j in iter.into_iter() {
65 match j {
66 Param::Value(v) => p.values.push(v),
67 Param::Data(d) => p.data.push(d),
68 Param::Fun(f) => p.funs.push(f),
69 }
70 }
71 return p;
72 }
73}
74impl<T: 'static, Y: 'static, R: 'static, D: 'static> IntoIterator for Params<T, Y, R, D> {
75 type Item = Param<T, Y, R, D>;
76
77 type IntoIter = Box<dyn Iterator<Item = Param<T, Y, R, D>>>;
78
79 fn into_iter(self) -> Self::IntoIter {
80 return Box::new(
81 self.values
82 .into_iter()
83 .map(Param::Value)
84 .chain(self.data.into_iter().map(Param::Data))
85 .chain(self.funs.into_iter().map(Param::Fun)),
86 );
87 }
88}
89
90pub enum ValueDef<T, Y, R, D> {
91 Param(usize),
92 Emit {
93 op: T,
94 params: Params<T, Y, R, D>,
95 typ: Y,
96 after: BTreeSet<Id<ValueDef<T, Y, R, D>>>,
97 },
98 Alias(Value<T, Y, R, D>),
99}
100
101impl<T: Clone, Y: Clone, R: Clone, D> Clone for ValueDef<T, Y, R, D> {
102 fn clone(&self) -> Self {
103 match self {
104 Self::Param(arg0) => Self::Param(arg0.clone()),
105 Self::Alias(arg0) => Self::Alias(arg0.clone()),
107 ValueDef::Emit {
109 op,
110 params,
111 typ,
112 after,
113 } => ValueDef::Emit {
114 op: op.clone(),
115 params: params.clone(),
116 typ: typ.clone(),
117 after: after.clone(),
118 },
119 }
121 }
122}
123
124pub struct Fun<T, Y, R, D> {
125 pub values: Arena<ValueDef<T, Y, R, D>>,
126 pub params: usize,
127 pub terminator: R,
128}
129impl<T, Y, R, D> Fun<T, Y, R, D> {
130 pub fn param(&mut self, a: usize) -> Value<T, Y, R, D> {
131 return Value {
132 id: self.values.alloc(ValueDef::Param(a)),
133 idx: None,
134 };
135 }
136}
137impl<T, Y, R: Default, D> Default for Fun<T, Y, R, D> {
138 fn default() -> Self {
139 Self {
140 values: Default::default(),
141 terminator: Default::default(),
142 params: Default::default(),
143 }
144 }
145}
146impl<T: Clone, Y: Clone, R: Clone, D> Clone for Fun<T, Y, R, D> {
147 fn clone(&self) -> Self {
148 Self {
149 values: self.values.clone(),
150 params: self.params.clone(),
151 terminator: self.terminator.clone(),
152 }
153 }
154}
155
156pub struct Module<T, Y, R, D> {
157 pub code: Arena<Fun<T, Y, R, D>>,
158 pub data: Arena<D>,
159}
160
161pub struct ModuleTransform<T, Y, R, D, S, L, E, P> {
162 pub input: Module<T, Y, R, D>,
163 pub out: Module<S, L, E, P>,
164 pub datum_cache: BTreeMap<Id<D>, Id<P>>,
165 pub code_cache: BTreeMap<Id<Fun<T, Y, R, D>>, Id<Fun<S, L, E, P>>>,
166}
167pub struct FuncTransformCtx<T, Y, R, D, S, L, E, P> {
168 pub input: Id<Fun<T, Y, R, D>>,
169 pub output: Id<Fun<S, L, E, P>>,
170}
171pub trait MTBehavior<T, Y, R, D, S, L, E, P> {
172 fn value(
173 &mut self,
174 ctx: &mut ModuleTransform<T, Y, R, D, S, L, E, P>,
175 fun_ctx: FuncTransformCtx<T, Y, R, D, S, L, E, P>,
176 def: ValueDef<T, Y, R, D>,
177 value: impl FnMut(
178 &mut Self,
179 &mut ModuleTransform<T, Y, R, D, S, L, E, P>,
180 Id<ValueDef<T, Y, R, D>>,
181 ) -> Id<ValueDef<S, L, E, P>>,
182 func: impl FnMut(
183 &mut Self,
184 &mut ModuleTransform<T, Y, R, D, S, L, E, P>,
185 Id<Fun<T, Y, R, D>>,
186 ) -> Id<Fun<S, L, E, P>>,
187 dat: impl FnMut(&mut Self, &mut ModuleTransform<T, Y, R, D, S, L, E, P>, Id<D>) -> Id<P>,
188 ) -> ValueDef<S, L, E, P>;
189 fn terminator(
190 &mut self,
191 ctx: &mut ModuleTransform<T, Y, R, D, S, L, E, P>,
192 fun_ctx: FuncTransformCtx<T, Y, R, D, S, L, E, P>,
193 def: R,
194 value: impl FnMut(
195 &mut Self,
196 &mut ModuleTransform<T, Y, R, D, S, L, E, P>,
197 Id<ValueDef<T, Y, R, D>>,
198 ) -> Id<ValueDef<S, L, E, P>>,
199 func: impl FnMut(
200 &mut Self,
201 &mut ModuleTransform<T, Y, R, D, S, L, E, P>,
202 Id<Fun<T, Y, R, D>>,
203 ) -> Id<Fun<S, L, E, P>>,
204 dat: impl FnMut(&mut Self, &mut ModuleTransform<T, Y, R, D, S, L, E, P>, Id<D>) -> Id<P>,
205 ) -> E;
206 fn datum(
207 &mut self,
208 ctx: &mut ModuleTransform<T, Y, R, D, S, L, E, P>,
209 def: D,
210 func: impl FnMut(
211 &mut Self,
212 &mut ModuleTransform<T, Y, R, D, S, L, E, P>,
213 Id<Fun<T, Y, R, D>>,
214 ) -> Id<Fun<S, L, E, P>>,
215 dat: impl FnMut(&mut Self, &mut ModuleTransform<T, Y, R, D, S, L, E, P>, Id<D>) -> Id<P>,
216 ) -> P;
217}
218pub type ValueTransMap<T, Y, R, D, S, L, E, P> =
219 Rc<RefCell<BTreeMap<Id<ValueDef<T, Y, R, D>>, Id<ValueDef<S, L, E, P>>>>>;
220impl<T: Clone, Y: Clone, R: Clone, D: Clone, S, L, E: Default, P>
221 ModuleTransform<T, Y, R, D, S, L, E, P>
222{
223 pub fn func_value<W: MTBehavior<T, Y, R, D, S, L, E, P>>(
224 &mut self,
225 w: &mut W,
226 f: Id<Fun<T, Y, R, D>>,
227 m: ValueTransMap<T, Y, R, D, S, L, E, P>,
228 a: Id<ValueDef<T, Y, R, D>>,
229 ) -> Id<ValueDef<S, L, E, P>> {
230 {
231 if let Some(x) = m.borrow_mut().get(&a) {
232 return *x;
233 }
234 }
235 let i = self.out.code[*self.code_cache.get(&f).unwrap()]
236 .values
237 .alloc(ValueDef::Param(usize::MAX));
238 let v = {
239 {
240 m.borrow_mut().insert(a.clone(), i.clone())
241 };
242 w.value(
243 self,
244 FuncTransformCtx {
245 input: f.clone(),
246 output: *self.code_cache.get(&f).unwrap(),
247 },
248 self.input.code[f].values[a].clone(),
249 |w, t, v| t.func_value(w, f, m.clone(), v),
250 |w, t, f| t.func(w, f),
251 |w, t, d| t.dat(w, d),
252 )
253 };
254 self.out.code[*self.code_cache.get(&f).unwrap()].values[i] = v;
255 return i;
256 }
257 pub fn func<W: MTBehavior<T, Y, R, D, S, L, E, P>>(
258 &mut self,
259 w: &mut W,
260 f: Id<Fun<T, Y, R, D>>,
261 ) -> Id<Fun<S, L, E, P>> {
262 if let Some(i) = self.code_cache.get(&f) {
263 return *i;
264 }
265 let me = self.out.code.alloc(Default::default());
266 let m = Rc::new(RefCell::new(BTreeMap::new()));
267 self.code_cache.insert(f.clone(), me.clone());
269 let a = &self.input.code[f.clone()];
270 let t = w.terminator(
271 self,
272 FuncTransformCtx {
273 input: f.clone(),
274 output: me.clone(),
275 },
276 self.input.code[f].terminator.clone(),
277 |w, t, v| t.func_value(w, f, m.clone(), v),
278 |w, t, f| t.func(w, f),
279 |w, t, d| t.dat(w, d),
280 );
281 self.out.code[me].terminator = t;
282 return me;
283 }
285 pub fn dat<W: MTBehavior<T, Y, R, D, S, L, E, P>>(&mut self, w: &mut W, dd: Id<D>) -> Id<P> {
286 if let Some(b) = self.datum_cache.get(&dd) {
287 return *b;
288 }
289 let d = w.datum(
290 self,
291 self.input.data[dd].clone(),
292 |w, t, f| t.func(w, f),
293 |w, t, d| t.dat(w, d),
294 );
295 let e = self.out.data.alloc(d);
296 self.datum_cache.insert(dd, e);
297 return e;
298 }
299}
300#[cfg(test)]
301mod tests {
302 use super::*;
303}