1use std::{borrow::Cow, fmt::Display, marker::PhantomData};
8
9use jstd::Identifier;
10
11use crate::value::{ModuleView, QCodeView, Value, ValueId, util::named::Named};
12
13#[derive(Identifier)]
15pub struct LocalTempSpaceId(usize);
16
17crate::composite_id!(TempSpaceId, LocalTempSpaceId);
18
19#[derive(Identifier)]
21pub struct LocalTempId(usize);
22
23crate::composite_id!(TempId, LocalTempId);
24
25#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
27pub struct TempSpace {
28 pub(crate) name: Option<Box<str>>,
29 pub(crate) word_size: usize,
30 pub(crate) addr_size: usize,
31}
32
33impl TempSpace {
34 pub fn new(name: Option<&str>, word_size: usize, addr_size: usize) -> Self {
35 Self {
36 name: name.map(Box::from),
37 word_size,
38 addr_size,
39 }
40 }
41}
42
43#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
45pub struct Temp<'str> {
46 pub(crate) name: Option<Cow<'str, str>>,
47 pub(crate) label: Option<u32>,
48 pub(crate) address: i64,
49 pub(crate) size: usize,
50 pub(crate) space: LocalTempSpaceId,
51}
52
53impl<'str> Temp<'str> {
54 pub fn new(address: i64, size: usize, space: LocalTempSpaceId) -> Self {
55 Self {
56 name: None,
57 label: None,
58 address,
59 size,
60 space,
61 }
62 }
63
64 pub fn with_name(mut self, name: Cow<'str, str>) -> Self {
67 self.name = Some(name);
68 self
69 }
70}
71
72#[derive(Clone, Copy)]
74pub struct TempSpaceRef<'str, 'ctx, R = ModuleView<'ctx, 'str>> {
75 pub id: TempSpaceId,
76 view: R,
77 marker: PhantomData<&'ctx &'str ()>,
78}
79
80impl<'str, 'ctx, R> TempSpaceRef<'str, 'ctx, R> {
81 pub fn new(view: R, id: TempSpaceId) -> Self {
82 Self {
83 id,
84 view,
85 marker: PhantomData,
86 }
87 }
88}
89
90impl<'str: 'ctx, 'ctx, R> TempSpaceRef<'str, 'ctx, R>
91where
92 R: QCodeView<'ctx, 'str>,
93{
94 fn inner(self) -> &'ctx TempSpace {
95 self.view.temp_space(self.id)
96 }
97
98 pub fn name(self) -> Option<&'ctx str> {
99 self.inner().name.as_deref()
100 }
101
102 pub fn word_size(self) -> usize {
103 self.inner().word_size
104 }
105
106 pub fn addr_size(self) -> usize {
107 self.inner().addr_size
108 }
109}
110
111impl<'str: 'ctx, 'ctx, R> Display for TempSpaceRef<'str, 'ctx, R>
112where
113 R: QCodeView<'ctx, 'str>,
114{
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 f.write_str(self.name().unwrap_or("temp"))
117 }
118}
119
120#[derive(Clone, Copy)]
122pub struct TempRef<'str, 'ctx, R = ModuleView<'ctx, 'str>> {
123 pub id: TempId,
124 pub(in crate::value) view: R,
125 marker: PhantomData<&'ctx &'str ()>,
126}
127
128impl<'str, 'ctx, R> TempRef<'str, 'ctx, R> {
129 pub fn new(view: R, id: TempId) -> Self {
130 Self {
131 id,
132 view,
133 marker: PhantomData,
134 }
135 }
136}
137
138impl<'str: 'ctx, 'ctx, R> TempRef<'str, 'ctx, R>
139where
140 R: QCodeView<'ctx, 'str>,
141{
142 fn inner(self) -> &'ctx Temp<'str> {
143 self.view.temp(self.id)
144 }
145
146 pub fn name(self) -> Option<&'ctx str> {
147 self.inner().name.as_deref()
148 }
149
150 pub fn label(self) -> Option<u32> {
151 self.inner().label
152 }
153
154 pub fn address(self) -> i64 {
155 self.inner().address
156 }
157
158 pub fn size(self) -> usize {
159 self.inner().size
160 }
161
162 pub fn space(self) -> TempSpaceRef<'str, 'ctx, R> {
163 TempSpaceRef::new(
164 self.view,
165 TempSpaceId::new(self.id.func, self.inner().space),
166 )
167 }
168
169 pub fn memory_space(self) -> crate::space::MemorySpaceId {
170 crate::space::MemorySpaceId::Temp(self.space().id)
171 }
172}
173
174impl<'str: 'ctx, 'ctx, R> Display for TempRef<'str, 'ctx, R>
175where
176 R: QCodeView<'ctx, 'str>,
177{
178 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
179 if let Some(name) = self.name() {
180 f.write_str(name)
181 } else if let Some(label) = self.label() {
182 write!(f, "v{label}")
183 } else {
184 write!(f, "[{}]:{} {}", self.space(), self.size(), self.address())
185 }
186 }
187}
188
189impl<'str: 'ctx, 'ctx, R> Named for TempRef<'str, 'ctx, R>
190where
191 R: QCodeView<'ctx, 'str>,
192{
193 fn name(&self) -> Option<&str> {
194 TempRef::name(*self)
195 }
196}
197
198impl<'str: 'ctx, 'ctx, R> Value<'str, 'ctx> for TempRef<'str, 'ctx, R>
199where
200 R: QCodeView<'ctx, 'str>,
201{
202 fn id(&self) -> ValueId {
203 ValueId::Temp(self.id)
204 }
205
206 fn size(&self) -> usize {
207 TempRef::size(*self)
208 }
209}