portal_jsc_swift_backend/
lib.rs1#![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}