portal_jsc_swift_backend/
lib.rs

1#![no_std]
2
3use core::fmt::Display;
4
5use alloc::{
6    collections::btree_map::BTreeMap,
7    format,
8    string::{String, ToString},
9    sync::Arc,
10    vec::Vec,
11};
12use itertools::Itertools;
13use symbolism::Symbol;
14extern crate alloc;
15#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
16#[repr(transparent)]
17pub struct SwiftName {
18    pub id: u64,
19}
20impl Display for SwiftName {
21    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
22        write!(
23            f,
24            "`js_{}`",
25            Symbol::from_int(self.id).to_string().replace(" ", "$")
26        )
27    }
28}
29#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
30#[repr(transparent)]
31pub struct TargetBlock {
32    pub name: SwiftName,
33}
34impl Display for TargetBlock {
35    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36        write!(
37            f,
38            "label = .{}
39            break",
40            &self.name
41        )
42    }
43}
44#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
45#[repr(transparent)]
46pub struct Return<T> {
47    pub value: T,
48}
49impl<T: Display> Display for Return<T> {
50    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
51        write!(f, "return {};", &self.value)
52    }
53}
54
55#[derive(Clone)]
56pub struct Blocks<K> {
57    pub map: BTreeMap<TargetBlock, Term<K>>,
58    pub entry: TargetBlock,
59}
60impl<K: Display> Display for Blocks<K> {
61    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
62        write!(
63            f,
64            "var label = .unused;while 1{{switch label{{{}\ndefault:{}}}}}",
65            self.map
66                .iter()
67                .map(|(t, k)| format!("case .{}: {k}", t.name))
68                .join("\n"),
69            self.entry
70        )
71    }
72}
73#[derive(Clone)]
74pub struct Term<K> {
75    pub blocks: Vec<K>,
76    pub term: Arc<dyn Fn(&[String]) -> String>,
77}
78impl<K> Term<K> {
79    pub fn raw(a: String) -> Self {
80        Self {
81            blocks: alloc::vec![],
82            term: Arc::new(move |_| a.clone()),
83        }
84    }
85    pub fn core(k: K) -> Self {
86        Self {
87            blocks: alloc::vec![k],
88            term: Arc::new(|a| a[0].clone()),
89        }
90    }
91    pub fn prepend_stmt(self, a: String) -> Self {
92        let Self { blocks, term } = self;
93        Self {
94            blocks,
95            term: Arc::new(move |s| {
96                let t = term(s);
97                alloc::format!("{a}\n{t}")
98            }),
99        }
100    }
101    pub fn r#if(self, cond: String, r#else: Term<K>) -> Self {
102        let a = self.blocks.len();
103        let b = self.term.clone();
104        let c = r#else.term;
105        Self {
106            blocks: self
107                .blocks
108                .into_iter()
109                .chain(r#else.blocks.into_iter())
110                .collect(),
111            term: Arc::new(move |s| {
112                let (a, d) = s.split_at(a);
113                let b = b(a);
114                let c = c(a);
115                alloc::format!("if {cond}{{{b}}}else{{{c}}}")
116            }),
117        }
118    }
119    pub fn map<U, E>(self, f: impl FnMut(K) -> Result<U, E>) -> Result<Term<U>, E> {
120        Ok(Term {
121            blocks: self.blocks.into_iter().map(f).collect::<Result<_, E>>()?,
122            term: self.term,
123        })
124    }
125    pub fn as_ref(&self) -> Term<&K> {
126        Term {
127            blocks: self.blocks.iter().collect(),
128            term: self.term.clone(),
129        }
130    }
131    pub fn as_mut(&mut self) -> Term<&mut K> {
132        Term {
133            blocks: self.blocks.iter_mut().collect(),
134            term: self.term.clone(),
135        }
136    }
137}
138impl<K: Display> Display for Term<K> {
139    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
140        write!(
141            f,
142            "{}",
143            (self.term)(
144                &self
145                    .blocks
146                    .iter()
147                    .map(|a| a.to_string())
148                    .collect::<Vec<_>>()
149            )
150        )
151    }
152}