1use std::ops::Deref;
2
3use py_lex::types::BasicExtenWord;
4
5use super::*;
6use crate::complex_pu;
7
8#[derive(Debug, Clone, Copy)]
10pub struct TypeConstExtend;
11
12impl ParseUnit<Token> for TypeConstExtend {
13 type Target = TypeConstExtend;
14
15 fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
16 p.r#match(BasicExtenWord::Const)?;
17
18 Ok(TypeConstExtend)
19 }
20}
21
22#[derive(Debug,Clone, Copy)]
23pub struct Size{
24 size: PU<usize>
25}
26
27impl Deref for Size{
28 type Target = usize;
29
30 fn deref(&self) -> &Self::Target {
31 &self.size
32 }
33}
34
35impl WithSpan for Size{
36 fn get_span(&self) -> Span {
37 self.size.get_span()
38 }
39}
40
41
42impl ParseUnit<Token> for Size{
43 type Target = Size;
44
45 fn parse(p: &mut Parser<Token>) -> terl::Result<Self::Target, ParseError> {
46 let token =p.parse::<Token>()?;
47 let size = match token.parse::<usize>(){
48 Ok(num) => PU::new(token.get_span(),num),
49 Err(pe) => return token.unmatch(format!("expect a number, but got `{}` while parsing",pe)),
50 };
51 Ok(Self { size })
52 }
53}
54#[derive(Debug, Clone, Copy)]
56pub struct TypeArrayExtend {
57 pub keyword: PU<BasicExtenWord>,
58 pub size: Option<Size>,
59}
60
61impl ParseUnit<Token> for TypeArrayExtend {
62 type Target = TypeArrayExtend;
63
64 fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
65 let keyword = p.r#match(RPU(BasicExtenWord::Array))?;
66 let size = p.parse::<Size>().apply(mapper::Try)?;
67 Ok(TypeArrayExtend { keyword, size })
68 }
69}
70
71#[derive(Debug, Clone, Copy)]
73pub struct TypeReferenceExtend;
74
75impl ParseUnit<Token> for TypeReferenceExtend {
76 type Target = TypeReferenceExtend;
77
78 fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
79 p.r#match(BasicExtenWord::Reference)?;
80 Ok(TypeReferenceExtend)
81 }
82}
83
84#[derive(Debug, Clone, Copy)]
86pub struct TypePointerExtend;
87
88impl ParseUnit<Token> for TypePointerExtend {
89 type Target = TypePointerExtend;
90
91 fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
92 p.r#match(BasicExtenWord::Pointer)?;
93 Ok(TypePointerExtend)
94 }
95}
96
97complex_pu! {
98 cpu TypeDecorators {
99 TypeArrayExtend,
100 TypeReferenceExtend,
101 TypePointerExtend
102 }
103}
104
105#[derive(Debug, Clone, Copy)]
108pub struct TypeWidthExtend {
109
110 pub width: Size,
111}
112
113impl ParseUnit<Token> for TypeWidthExtend {
114 type Target = TypeWidthExtend;
115
116 fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
117 p.r#match(BasicExtenWord::Width)?;
118 let width = p.parse::<Size>().apply(mapper::MustMatch)?;
119
120 Ok(TypeWidthExtend { width })
121 }
122}
123
124#[derive(Debug, Clone, Copy)]
127pub struct TypeSignExtend {
128 pub sign: bool,
129}
130
131impl ParseUnit<Token> for TypeSignExtend {
132 type Target = TypeSignExtend;
133
134 fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
135 let keyword = p.parse::<PU<BasicExtenWord>>()?;
136 let sign = match *keyword {
137 BasicExtenWord::Signed => true,
138 BasicExtenWord::Unsigned => false,
139 _ => {
140 return keyword.throw("should be `you3fu2` or `wu2fu2`");
141 }
142 };
143
144 Ok(TypeSignExtend { sign })
145 }
146}
147
148#[derive(Debug, Clone)]
149pub struct TypeDefine {
150 pub const_: Option<PU<TypeConstExtend>>,
151 pub decorators: Vec<PU<TypeDecorators>>,
152 pub width: Option<PU<TypeWidthExtend>>,
153 pub sign: Option<PU<TypeSignExtend>>,
154 pub ty: Ident,
155}
156
157impl TypeDefine {
158 pub(crate) fn to_mir_ty(&self) -> terl::Result<crate::ir::types::TypeDefine> {
159 self.try_into()
160 }
161}
162
163impl TryFrom<&TypeDefine> for crate::ir::types::TypeDefine {
164 type Error = terl::Error;
165
166 fn try_from(def: &crate::parse::TypeDefine) -> std::result::Result<Self, Self::Error> {
167 use crate::ir::types::{ComplexType, PrimitiveType};
168 if &*def.ty == "zheng3" {
174 let sign = def.sign.map(|pu| pu.sign).unwrap_or(true);
176
177 let width = if let Some(width_extend) = def.width {
178 if !width_extend.width.is_power_of_two()
179 || *width_extend.width > 128
180 || *width_extend.width < 64
181 {
182 return Err(width_extend.make_error(format!(
183 "`zheng3` with width {} is not suppert now",
184 *width_extend.width
185 )));
186 }
187 *width_extend.width
188 } else {
189 64
190 };
191
192 use PrimitiveType::*;
193 #[rustfmt::skip]
194 let ty = match width {
195 8 => if sign { I8 } else { U8 },
196 16 => if sign { I16 } else { U16 },
197 32 => if sign { I32 } else { U32 },
198 64 => if sign { I64 } else { U64 },
199 128 => if sign { I128 } else { U128 },
200 _ => unreachable!(),
201 };
202 return Ok(ty.into());
203 } else if &*def.ty == "fu2" {
204 if let Some(sign) = def.sign {
206 return Err(
207 sign.make_error("`fu2` type cant be decorated with `you3fu2` or `wu2fu2`")
208 );
209 }
210 let width = if let Some(width) = def.width {
211 if *width.width == 32 || *width.width == 64 {
212 *width.width
213 } else {
214 return Err(width.make_error(format!(
215 "`fu2` with width {} is not supperted now",
216 *width.width
217 )));
218 }
219 } else {
220 32
221 };
222
223 let ty = match width {
224 32 => PrimitiveType::F32,
225 64 => PrimitiveType::F64,
226 _ => unreachable!(),
227 };
228 return Ok(ty.into());
229 }
230
231 if let Some(sign) = def.sign {
232 return Err(sign.make_error(format!(
233 "type `{}` with `you3fu2` or `wu2fu2` is not supperted now",
234 def.ty
235 )));
236 }
237 if let Some(width) = def.width {
238 return Err(width.make_error(format!(
239 "type `{}` with `you3fu2` or `wu2fu2` is not supperted now",
240 def.ty
241 )));
242 }
243 let ty = def.ty.to_string();
244
245 if def.const_.is_none() && def.decorators.is_empty() {
246 return Ok(ComplexType::no_decorators(ty).into());
247 }
248
249 use crate::ir::types::TypeDecorators::*;
250
251 let mut decorators = vec![];
252 if def.const_.is_some() {
253 decorators.push(Const);
254 }
255
256 for decorator in &def.decorators {
257 let decorator = match &**decorator{
258 crate::parse::TypeDecorators::TypeArrayExtend(array) => match array.size {
259 Some(size) => SizedArray(*size),
260 None => Array,
261 },
262 crate::parse::TypeDecorators::TypeReferenceExtend(_) => {
263 Reference
264 }
265 crate::parse::TypeDecorators::TypePointerExtend(_) => {
266 Pointer
267 }
268 };
269 decorators.push(decorator);
270 }
271
272 Ok(ComplexType { decorators, ty }.into())
273 }
274}
275
276impl ParseUnit<Token> for TypeDefine {
277 type Target = TypeDefine;
278
279 fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
280 let const_ = p.parse::<PU<TypeConstExtend>>().apply(mapper::Try)?;
281 let mut decorators = vec![];
282 while let Some(decorator) = p.parse::<PU<TypeDecorators>>().apply(mapper::Try)? {
283 decorators.push(decorator);
284 }
285 let width = p.parse::<PU<TypeWidthExtend>>().apply(mapper::Try)?;
286 let sign = p.parse::<PU<TypeSignExtend>>().apply(mapper::Try)?;
287 let ty = p.parse::<Ident>()?;
288 Ok(TypeDefine {
289 const_,
290 decorators,
291 width,
292 sign,
293 ty,
294 })
295 }
296}
297
298#[cfg(test)]
299mod tests {
300 use crate::parse_test;
301
302 use super::*;
303
304 #[test]
305 fn fucking_type() {
306 parse_test("yin3 zu3 114514 kuan1 32 wu2fu2 zheng3", |p| {
307 p.parse::<TypeDefine>()?;
308 Ok(())
309 })
310 }
311}