Skip to main content

portal_jsc_common/
lib.rs

1#![no_std]
2use core::iter::once;
3pub use portal_pc_asm_common as asm;
4
5use either::Either;
6
7#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
8#[non_exhaustive]
9pub enum Native<E> {
10    AssertString { value: E, comptime: bool },
11    AssertNumber { value: E, comptime: bool },
12    AssertStaticFn { value: E, comptime: bool },
13    FastAdd { lhs: E, rhs: E },
14    FastAnd { lhs: E, rhs: E },
15    FastOr { lhs: E, rhs: E },
16    FastEq { lhs: E, rhs: E },
17    FastSub { lhs: E, rhs: E },
18    FastMul { lhs: E, rhs: E, imul: bool },
19    FastShl { lhs: E, rhs: E },
20}
21impl Native<()> {
22    pub fn of(a: &str) -> Option<Self> {
23        Some(match a {
24            "assert_string" => Self::AssertString {
25                value: (),
26                comptime: false,
27            },
28            "assert_number" => Self::AssertNumber {
29                value: (),
30                comptime: false,
31            },
32            "assert_static_fn" => Self::AssertStaticFn {
33                value: (),
34                comptime: false,
35            },
36            "comptime_string" => Self::AssertString {
37                value: (),
38                comptime: true,
39            },
40            "comptime_number" => Self::AssertNumber {
41                value: (),
42                comptime: true,
43            },
44            "comptime_static_fn" => Self::AssertStaticFn {
45                value: (),
46                comptime: true,
47            },
48            "fast_add" => Self::FastAdd { lhs: (), rhs: () },
49            "fast_and" => Self::FastAnd { lhs: (), rhs: () },
50            "fast_or" => Self::FastOr { lhs: (), rhs: () },
51            "fast_eq" => Self::FastEq { lhs: (), rhs: () },
52            "fast_sub" => Self::FastSub { lhs: (), rhs: () },
53            "fast_shl" => Self::FastShl { lhs: (), rhs: () },
54            "fast_mul" => Self::FastMul {
55                lhs: (),
56                rhs: (),
57                imul: false,
58            },
59            "fast_imul" => Self::FastMul {
60                lhs: (),
61                rhs: (),
62                imul: true,
63            },
64            _ => return None,
65        })
66    }
67}
68impl<E> Native<E> {
69    pub fn key(&self) -> &'static str {
70        match self {
71            Native::AssertString { value, comptime } => {
72                if *comptime {
73                    "comptime_string"
74                } else {
75                    "assert_string"
76                }
77            }
78            Native::AssertNumber { value, comptime } => {
79                if *comptime {
80                    "comptime_number"
81                } else {
82                    "aasert_number"
83                }
84            }
85            Native::AssertStaticFn { value, comptime } => {
86                if *comptime {
87                    "comptime_static_fn"
88                } else {
89                    "assert_static_fn"
90                }
91            }
92            Native::FastAdd { lhs, rhs } => "fast_add",
93            Native::FastAnd { lhs, rhs } => "fast_and",
94            Native::FastOr { lhs, rhs } => "fast_or",
95            Native::FastEq { lhs, rhs } => "fast_eq",
96            Native::FastSub { lhs, rhs } => "fast_sub",
97            Native::FastMul { lhs, rhs, imul } => {
98                if *imul {
99                    "fast_imul"
100                } else {
101                    "fast_mul"
102                }
103            }
104            Native::FastShl { lhs, rhs } => "fast_shl",
105        }
106    }
107    pub fn as_ref<'a>(&'a self) -> Native<&'a E> {
108        match self {
109            Native::AssertString { value, comptime } => Native::AssertString {
110                value,
111                comptime: *comptime,
112            },
113            Native::AssertNumber { value, comptime } => Native::AssertNumber {
114                value,
115                comptime: *comptime,
116            },
117            Native::AssertStaticFn { value, comptime } => Native::AssertStaticFn {
118                value,
119                comptime: *comptime,
120            },
121            Native::FastAdd { lhs, rhs } => Native::FastAdd { lhs, rhs },
122            Native::FastAnd { lhs, rhs } => Native::FastAnd { lhs, rhs },
123            Native::FastOr { lhs, rhs } => Native::FastOr { lhs, rhs },
124            Native::FastEq { lhs, rhs } => Native::FastEq { lhs, rhs },
125            Native::FastSub { lhs, rhs } => Native::FastSub { lhs, rhs },
126            Native::FastMul { lhs, rhs, imul } => Native::FastMul {
127                lhs,
128                rhs,
129                imul: *imul,
130            },
131            Native::FastShl { lhs, rhs } => Native::FastShl { lhs, rhs },
132        }
133    }
134    pub fn as_mut<'a>(&'a mut self) -> Native<&'a mut E> {
135        match self {
136            Native::AssertString { value, comptime } => Native::AssertString {
137                value,
138                comptime: *comptime,
139            },
140            Native::AssertNumber { value, comptime } => Native::AssertNumber {
141                value,
142                comptime: *comptime,
143            },
144            Native::AssertStaticFn { value, comptime } => Native::AssertStaticFn {
145                value,
146                comptime: *comptime,
147            },
148            Native::FastAdd { lhs, rhs } => Native::FastAdd { lhs, rhs },
149            Native::FastAnd { lhs, rhs } => Native::FastAnd { lhs, rhs },
150            Native::FastOr { lhs, rhs } => Native::FastOr { lhs, rhs },
151            Native::FastEq { lhs, rhs } => Native::FastEq { lhs, rhs },
152            Native::FastSub { lhs, rhs } => Native::FastSub { lhs, rhs },
153            Native::FastMul { lhs, rhs, imul } => Native::FastMul {
154                lhs,
155                rhs,
156                imul: *imul,
157            },
158            Native::FastShl { lhs, rhs } => Native::FastShl { lhs, rhs },
159        }
160    }
161    pub fn map<E2, Er>(self, f: &mut impl FnMut(E) -> Result<E2, Er>) -> Result<Native<E2>, Er> {
162        Ok(match self {
163            Native::AssertString { value, comptime } => Native::AssertString {
164                value: f(value)?,
165                comptime,
166            },
167            Native::AssertNumber { value, comptime } => Native::AssertNumber {
168                value: f(value)?,
169                comptime,
170            },
171            Native::AssertStaticFn { value, comptime } => Native::AssertStaticFn {
172                value: f(value)?,
173                comptime,
174            },
175            Native::FastAdd { lhs, rhs } => Native::FastAdd {
176                lhs: f(lhs)?,
177                rhs: f(rhs)?,
178            },
179            Native::FastAnd { lhs, rhs } => Native::FastAnd {
180                lhs: f(lhs)?,
181                rhs: f(rhs)?,
182            },
183            Native::FastOr { lhs, rhs } => Native::FastOr {
184                lhs: f(lhs)?,
185                rhs: f(rhs)?,
186            },
187            Native::FastEq { lhs, rhs } => Native::FastEq {
188                lhs: f(lhs)?,
189                rhs: f(rhs)?,
190            },
191            Native::FastSub { lhs, rhs } => Native::FastSub {
192                lhs: f(lhs)?,
193                rhs: f(rhs)?,
194            },
195            Native::FastMul { lhs, rhs, imul } => Native::FastMul {
196                lhs: f(lhs)?,
197                rhs: f(rhs)?,
198                imul,
199            },
200            Native::FastShl { lhs, rhs } => Native::FastShl {
201                lhs: f(lhs)?,
202                rhs: f(rhs)?,
203            },
204        })
205    }
206}
207
208#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
209#[non_exhaustive]
210pub enum LId<I, M: IntoIterator<Item = I> = [I; 1]> {
211    Id { id: I },
212    Member { obj: I, mem: M },
213}
214impl<I> LId<I> {
215    pub fn map<J, E>(self, f: &mut impl FnMut(I) -> Result<J, E>) -> Result<LId<J>, E> {
216        self.map2(f, &mut |cx, a| cx(a), &mut |cx, [a]| cx(a).map(|b| [b]))
217    }
218}
219impl<I, M: IntoIterator<Item = I>> LId<I, M> {
220    pub fn as_ref<'a>(&'a self) -> LId<&'a I, &'a M>
221    where
222        &'a M: IntoIterator<Item = &'a I>,
223    {
224        match self {
225            LId::Id { id } => LId::Id { id },
226            LId::Member { obj, mem } => LId::Member { obj, mem },
227        }
228    }
229    pub fn as_mut<'a>(&'a mut self) -> LId<&'a mut I, &'a mut M>
230    where
231        &'a mut M: IntoIterator<Item = &'a mut I>,
232    {
233        match self {
234            LId::Id { id } => LId::Id { id },
235            LId::Member { obj, mem } => LId::Member { obj, mem },
236        }
237    }
238    pub fn refs(self) -> impl Iterator<Item = I> {
239        match self {
240            LId::Id { id } => Either::Left(once(id)),
241            LId::Member { obj, mem } => Either::Right(once(obj).chain(mem)),
242        }
243    }
244    pub fn map2<Cx, J, N: IntoIterator<Item = J>, E>(
245        self,
246        cx: &mut Cx,
247        f: &mut (dyn FnMut(&mut Cx, I) -> Result<J, E> + '_),
248        g: &mut (dyn FnMut(&mut Cx, M) -> Result<N, E> + '_),
249    ) -> Result<LId<J, N>, E> {
250        Ok(match self {
251            LId::Id { id } => LId::Id { id: f(cx, id)? },
252            LId::Member { obj, mem } => LId::Member {
253                obj: f(cx, obj)?,
254                mem: g(cx, mem)?,
255            },
256        })
257    }
258}
259#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
260pub enum ImportMap<T> {
261    Default,
262    Star,
263    Named { name: T },
264}
265#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)]
266#[non_exhaustive]
267pub enum Asm<I> {
268    OrZero(I),
269}
270impl<I> Asm<I> {
271    pub fn as_ref(&self) -> Asm<&I> {
272        match self {
273            Asm::OrZero(a) => Asm::OrZero(a),
274        }
275    }
276    pub fn as_mut(&mut self) -> Asm<&mut I> {
277        match self {
278            Asm::OrZero(a) => Asm::OrZero(a),
279        }
280    }
281    pub fn map<J, E>(self, f: &mut impl FnMut(I) -> Result<J, E>) -> Result<Asm<J>, E> {
282        Ok(match self {
283            Asm::OrZero(a) => Asm::OrZero(f(a)?),
284        })
285    }
286    pub fn refs(&self) -> impl Iterator<Item = &I> {
287        match self {
288            Asm::OrZero(a) => once(a),
289        }
290    }
291    pub fn refs_mut(&mut self) -> impl Iterator<Item = &mut I> {
292        match self {
293            Asm::OrZero(a) => once(a),
294        }
295    }
296}