ssa_traits/
lib.rs

1#![no_std]
2
3use core::{iter::once, ops::Index};
4
5extern crate alloc;
6use alloc::boxed::Box;
7use alloc::vec;
8use alloc::vec::Vec;
9
10use arena_traits::Arena;
11use either::Either;
12pub mod op;
13pub trait Func: cfg_traits::Func<Blocks: Arena<Self::Block, Output: Block<Self>>> {
14    type Value;
15    type Values: Arena<Self::Value, Output: Value<Self>>;
16    fn values(&self) -> &Self::Values;
17    fn values_mut(&mut self) -> &mut Self::Values;
18}
19pub type ValueI<F> = <<F as Func>::Values as Index<<F as Func>::Value>>::Output;
20pub type BlockI<F> =
21    <<F as cfg_traits::Func>::Blocks as Index<<F as cfg_traits::Func>::Block>>::Output;
22pub type TermI<F> = <BlockI<F> as cfg_traits::Block<F>>::Terminator;
23pub type TargetI<F> = <TermI<F> as cfg_traits::Term<F>>::Target;
24
25#[repr(transparent)]
26pub struct Val<F: Func + ?Sized>(pub F::Value);
27impl<F: Func<Value: Clone> + ?Sized> Clone for Val<F> {
28    fn clone(&self) -> Self {
29        Self(self.0.clone())
30    }
31}
32impl<F: Func<Value: Clone> + ?Sized> HasValues<F> for Val<F> {
33    fn values<'a>(&'a self, f: &'a F) -> Box<(dyn Iterator<Item = <F as Func>::Value> + 'a)> {
34        Box::new(once(self.0.clone()))
35    }
36
37    fn values_mut<'a>(
38        &'a mut self,
39        g: &'a mut F,
40    ) -> Box<(dyn Iterator<Item = &'a mut <F as Func>::Value> + 'a)>
41    where
42        F: 'a,
43    {
44        Box::new(once(&mut self.0))
45    }
46}
47impl<F: Func<Value: Clone> + ?Sized> HasChainableValues<F> for Val<F> {
48    fn values_chain<'a>(&'a self) -> Box<(dyn Iterator<Item = <F as Func>::Value> + 'a)> {
49        Box::new(once(self.0.clone()))
50    }
51
52    fn values_chain_mut<'a>(
53        &'a mut self,
54    ) -> Box<(dyn Iterator<Item = &'a mut <F as Func>::Value> + 'a)>
55    where
56        F: 'a,
57    {
58        Box::new(once(&mut self.0))
59    }
60}
61impl<F: Func<Value: Clone> + ?Sized> HasValues<F> for Vec<F::Value> {
62    fn values<'a>(&'a self, f: &'a F) -> Box<(dyn Iterator<Item = <F as Func>::Value> + 'a)> {
63        Box::new(self.iter().cloned())
64    }
65
66    fn values_mut<'a>(
67        &'a mut self,
68        g: &'a mut F,
69    ) -> Box<(dyn Iterator<Item = &'a mut <F as Func>::Value> + 'a)>
70    where
71        F: 'a,
72    {
73        Box::new(self.iter_mut())
74    }
75}
76impl<F: Func<Value: Clone> + ?Sized> HasChainableValues<F> for Vec<F::Value> {
77    fn values_chain<'a>(&'a self) -> Box<(dyn Iterator<Item = <F as Func>::Value> + 'a)> {
78        Box::new(self.iter().cloned())
79    }
80
81    fn values_chain_mut<'a>(
82        &'a mut self,
83    ) -> Box<(dyn Iterator<Item = &'a mut <F as Func>::Value> + 'a)>
84    where
85        F: 'a,
86    {
87        Box::new(self.iter_mut())
88    }
89}
90pub struct BuildFn<F> {
91    pub func: F,
92}
93pub fn build_fn<F: FnOnce(&mut G, G::Block) -> anyhow::Result<(R, G::Block)>, G: Func, R>(
94    f: F,
95) -> BuildFn<F> {
96    BuildFn { func: f }
97}
98pub trait CpsBuilder<F: Func> {
99    type Result;
100    fn go<'a: 'b + 'c, 'b, 'c, R>(
101        self,
102        f: &'b mut F,
103        k: F::Block,
104        next: Box<dyn FnMut(&mut F, Self::Result, F::Block) -> anyhow::Result<R> + 'c>,
105    ) -> Box<dyn Iterator<Item = anyhow::Result<R>> + 'a>;
106}
107pub trait Builder<F: Func> {
108    type Result;
109    fn build(self, f: &mut F, k: F::Block) -> anyhow::Result<(Self::Result, F::Block)>;
110}
111impl<F: Func, B: Builder<F>> Builder<F> for anyhow::Result<B> {
112    type Result = B::Result;
113
114    fn build(
115        self,
116        f: &mut F,
117        k: <F as cfg_traits::Func>::Block,
118    ) -> anyhow::Result<(Self::Result, <F as cfg_traits::Func>::Block)> {
119        self?.build(f, k)
120    }
121}
122impl<F: FnOnce(&mut G, G::Block) -> anyhow::Result<(R, G::Block)>, G: Func, R> Builder<G> for F {
123    type Result = R;
124
125    fn build(
126        self,
127        f: &mut G,
128        k: <G as cfg_traits::Func>::Block,
129    ) -> anyhow::Result<(Self::Result, <G as cfg_traits::Func>::Block)> {
130        self(f, k)
131    }
132}
133pub trait Block<F: Func<Blocks: Arena<F::Block, Output = Self>> + ?Sized>:
134    cfg_traits::Block<F, Terminator: Term<F>>
135{
136    fn insts(&self) -> impl Iterator<Item = F::Value>;
137    fn add_inst(func: &mut F, key: F::Block, v: F::Value);
138}
139pub trait Value<F: Func<Values: Arena<F::Value, Output = Self>> + ?Sized>: HasValues<F> {}
140
141pub trait TypedValue<F: TypedFunc<Values: Arena<F::Value, Output = Self>> + ?Sized>:
142    Value<F>
143{
144    fn ty(&self, f: &F) -> F::Ty;
145}
146pub trait TypedFunc:
147    Func<
148    Values: Arena<Self::Value, Output: TypedValue<Self>>,
149    Blocks: Arena<Self::Block, Output: TypedBlock<Self>>,
150>
151{
152    type Ty;
153    fn add_blockparam(&mut self, k: Self::Block, y: Self::Ty) -> Self::Value;
154}
155pub trait TypedBlock<F: TypedFunc<Blocks: Arena<F::Block, Output = Self>> + ?Sized>:
156    Block<F>
157{
158    fn params(&self) -> impl Iterator<Item = (F::Ty, F::Value)>;
159}
160
161pub trait HasValues<F: Func + ?Sized> {
162    fn values<'a>(&'a self, f: &'a F) -> Box<dyn Iterator<Item = F::Value> + 'a>;
163    fn values_mut<'a>(
164        &'a mut self,
165        g: &'a mut F,
166    ) -> Box<dyn Iterator<Item = &'a mut F::Value> + 'a>
167    where
168        F: 'a;
169}
170pub trait FromValues<F: Func + ?Sized>: HasValues<F> {
171    fn from_values(f: &mut F, i: impl Iterator<Item = F::Value>) -> Self;
172}
173pub trait HasChainableValues<F: Func + ?Sized>: HasValues<F> {
174    fn values_chain<'a>(&'a self) -> Box<dyn Iterator<Item = F::Value> + 'a>;
175    fn values_chain_mut<'a>(&'a mut self) -> Box<dyn Iterator<Item = &'a mut F::Value> + 'a>
176    where
177        F: 'a;
178}
179impl<F: Func + ?Sized, A: HasValues<F>, B: HasValues<F>> HasValues<F> for Either<A, B> {
180    fn values<'a>(&'a self, f: &'a F) -> Box<(dyn Iterator<Item = <F as Func>::Value> + 'a)> {
181        match self {
182            Either::Left(a) => a.values(f),
183            Either::Right(b) => b.values(f),
184        }
185    }
186
187    fn values_mut<'a>(
188        &'a mut self,
189        f: &'a mut F,
190    ) -> Box<(dyn Iterator<Item = &'a mut <F as Func>::Value> + 'a)>
191    where
192        F: 'a,
193    {
194        match self {
195            Either::Left(a) => a.values_mut(f),
196            Either::Right(b) => b.values_mut(f),
197        }
198    }
199}
200impl<F: Func + ?Sized, A: HasChainableValues<F>, B: HasChainableValues<F>> HasChainableValues<F>
201    for Either<A, B>
202{
203    fn values_chain<'a>(&'a self) -> Box<(dyn Iterator<Item = <F as Func>::Value> + 'a)> {
204        match self {
205            Either::Left(a) => a.values_chain(),
206            Either::Right(b) => b.values_chain(),
207        }
208    }
209
210    fn values_chain_mut<'a>(
211        &'a mut self,
212    ) -> Box<(dyn Iterator<Item = &'a mut <F as Func>::Value> + 'a)>
213    where
214        F: 'a,
215    {
216        match self {
217            Either::Left(a) => a.values_chain_mut(),
218            Either::Right(b) => b.values_chain_mut(),
219        }
220    }
221}
222pub trait Target<F: Func + ?Sized>: HasValues<F> + cfg_traits::Target<F> {
223    fn push_value(&mut self, v: F::Value);
224    fn from_values_and_block(a: impl Iterator<Item = F::Value>, k: F::Block) -> Self;
225}
226pub trait Term<F: Func + ?Sized>: HasValues<F> + cfg_traits::Term<F, Target: Target<F>> {}
227impl<F: Func + ?Sized, T: HasValues<F> + cfg_traits::Term<F, Target: Target<F>>> Term<F> for T {}