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}