1use mist_parser::ast::*;
2
3use crate::Context;
4
5use crate::{GenRust, GetRust, RustCodegen};
6
7impl GetRust for GenericsDecl {
8 fn get_rust(&self) -> String {
9 if self.0.len() == 0 {
10 String::new()
11 } else {
12 format!(
13 "<{}>",
14 self.0
15 .iter()
16 .map(|v| v.get_rust())
17 .collect::<Vec<_>>()
18 .join(", ")
19 )
20 }
21 }
22}
23
24impl GetRust for GenericDecl {
25 fn get_rust(&self) -> String {
26 match self {
27 GenericDecl::Lifetime(name) => format!("'{}", name.get_rust()),
28 GenericDecl::Type(name, requirements) => {
29 name.get_rust()
30 + &(if requirements.len() != 0 {
31 format!(
32 ": {}",
33 requirements
34 .into_iter()
35 .map(TypeExpr::get_rust)
36 .collect::<Vec<_>>()
37 .join("+")
38 )
39 } else {
40 String::new()
41 })
42 }
43 }
44 }
45}
46
47impl GenRust for ImplDecl {
48 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
49 if let Some(trait_) = &self.trait_ {
50 cg.add_indentedln(&format!(
51 "impl{} {} for {} {{",
52 self.generics.get_rust(),
53 trait_.get_rust(),
54 self.target.get_rust()
55 ));
56 } else {
57 cg.add_indentedln(&format!(
58 "impl{} {} {{",
59 self.generics.get_rust(),
60 self.target.get_rust()
61 ));
62 }
63 cg.indent += 1;
64
65 for method in &self.methods {
66 method.gen_rust(ctx, cg);
67 }
68
69 cg.indent -= 1;
70 cg.add_indentedln("}");
71 }
72}
73
74impl GenRust for FunctionDecl {
75 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
76 cg.add(&format!(
77 "{}fn {}{}(",
78 self.visibility.get_rust(),
79 self.name.get_rust(),
80 self.generics.get_rust(),
81 ));
82
83 for (i, param) in self.params.0.iter().enumerate() {
84 if i > 0 {
85 cg.add(", ");
86 }
87
88 param.gen_rust(ctx, cg);
89 }
90
91 cg.add(") -> ");
92 cg.add(&self.return_type.get_rust());
93
94 if let Some(body) = &self.body {
95 cg.add(" ");
96 body.gen_rust(ctx, cg);
97 } else {
98 cg.add(";");
99 }
100 }
101}
102
103impl GetRust for FieldDecl {
104 fn get_rust(&self) -> String {
105 format!(
106 "{}{}: {},",
107 self.visibility.get_rust(),
108 self.name.get_rust(),
109 self.type_.get_rust()
110 )
111 }
112}
113
114impl GetRust for EnumItem {
115 fn get_rust(&self) -> String {
116 match self {
117 Self::Named(id) => id.get_rust(),
118 Self::Struct(id, s) => format!(
119 "{} {{{}}}",
120 id.get_rust(),
121 s.into_iter()
122 .map(|field| format!("{}: {}", field.name.get_rust(), field.type_.get_rust()))
123 .collect::<Vec<_>>()
124 .join(", ")
125 ),
126 Self::Tuple(id, t) => format!(
127 "{} ({})",
128 id.get_rust(),
129 t.into_iter()
130 .map(TypeExpr::get_rust)
131 .collect::<Vec<_>>()
132 .join(", ")
133 ),
134 }
135 }
136}
137
138impl GenRust for ParamList {
139 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
140 for (i, param) in self.0.iter().enumerate() {
141 if i > 0 {
142 cg.add(", ");
143 }
144
145 param.gen_rust(ctx, cg);
146 }
147 }
148}
149
150impl GenRust for TopLevel {
151 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
152 if let TopLevelKind::ModAttribute = self.0.item {
153 for attr in &self.1 {
154 cg.add("#![");
155 attr.gen_rust(ctx, cg);
156 cg.addln("]");
157 }
158 } else {
159 for attr in &self.1 {
160 cg.add("#[");
161 attr.gen_rust(ctx, cg);
162 cg.addln("]");
163 }
164 }
165
166 self.0.gen_rust(ctx, cg);
167 }
168}
169
170impl GenRust for (&Vec<Spanned<FieldDeclStmt>>, &Spanned<ClassConstructor>) {
171 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
172 cg.add_indented(&format!(
173 "{}fn new{}(",
174 self.1.item.visibility.get_rust(),
175 self.1.item.generics.get_rust()
176 ));
177
178 let params = self
179 .1
180 .item
181 .params
182 .0
183 .clone()
184 .into_iter()
185 .enumerate()
186 .map(|(idx, mut v)| {
187 v.name = construct_pattern(&v.name, idx);
188 (idx, v)
189 })
190 .collect::<Vec<_>>();
191
192 for (i, param) in ¶ms {
193 if *i > 0 {
194 cg.add(", ");
195 }
196
197 param.gen_rust(ctx, cg);
198 }
199
200 cg.addln(") -> Self {");
201 cg.indent += 1;
202
203 cg.add_indentedln("let mut this: Self = unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };");
204
205 for field in self.0 {
206 let comment = field.get_comment();
207
208 if let Some(init) = &field.item.init {
209 cg.add_indentedln(&comment);
210
211 cg.add_indentedln(&format!("this.{} = ", field.item.decl.name.get_rust()));
212
213 init.gen_rust(ctx, cg);
214 }
215 }
216
217 cg.add_indented(&format!("this.constructor("));
218
219 for (i, param) in params {
220 if i > 0 {
221 cg.add(", ");
222 }
223
224 ctx.expr_ensure_semicolon = false;
225 param.name.gen_rust(ctx, cg);
226 }
227
228 cg.addln(");");
229
230 cg.add_indentedln("this");
231
232 cg.indent -= 1;
233 cg.add_indentedln("}\n");
234
235 let mut constructor_params = vec![VarDecl {
236 name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])),
237 type_: Some(TypeExpr(
238 TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))]), None),
239 vec![TypePostfix::RefMut],
240 )),
241 }];
242
243 constructor_params.append(&mut self.1.item.params.0.clone());
244
245 Spanned {
246 line: self.1.line,
247 column: self.1.column,
248 item: FunctionDecl {
249 visibility: self.1.item.visibility.clone(),
250 name: Identifier(String::from("constructor")),
251 generics: self.1.item.generics.clone(),
252 params: ParamList(constructor_params),
253 return_type: TypeExpr::no_px(TypeExprKind::Tuple(Vec::new())),
254 body: Some(self.1.item.body.clone()),
255 },
256 }
257 .gen_rust(ctx, cg);
258 }
259}
260
261fn construct_pattern(pat: &Pattern, idx: usize) -> Pattern {
262 match pat {
263 Pattern::Literal(v) => Pattern::Literal(v.clone()),
264 Pattern::Path(is_mut, v) => Pattern::Path(*is_mut, v.clone().into()),
265 _ => Pattern::Path(false, Path(vec![Identifier(format!("_{idx}"))])),
266 }
267}
268
269impl GenRust for TopLevelKind {
270 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
271 match self {
272 Self::ModAttribute => {}
273 Self::Import(vis, path) => {
274 cg.addln(&format!("{}use {};", vis.get_rust(), path.get_rust()))
275 }
276 Self::Mod(vis, id) => cg.addln(&format!("{}mod {};", vis.get_rust(), id.get_rust())),
277 Self::FunctionDecl(decl) => decl.gen_rust(ctx, cg),
278 Self::ImplDecl(impl_) => impl_.gen_rust(ctx, cg),
279 Self::StructDecl {
280 visibility,
281 name,
282 generics,
283 fields,
284 } => {
285 cg.addln(&format!(
286 "{}struct {}{} {{",
287 visibility.get_rust(),
288 name.get_rust(),
289 generics.get_rust()
290 ));
291 cg.indent += 1;
292
293 for field in fields {
294 cg.add_indentedln(&field.get_rust());
295 }
296
297 cg.indent -= 1;
298 cg.addln("}\n");
299 }
300 Self::EnumDecl {
301 visibility,
302 name,
303 generics,
304 fields,
305 } => {
306 cg.addln(&format!(
307 "{}enum {}{} {{",
308 visibility.get_rust(),
309 name.get_rust(),
310 generics.get_rust()
311 ));
312 cg.indent += 1;
313
314 for field in fields {
315 cg.add_indentedln(&(field.get_rust() + ","));
316 }
317
318 cg.indent -= 1;
319 cg.addln("}\n");
320 }
321 Self::TraitDecl {
322 visibility,
323 name,
324 generics,
325 requirements,
326 items,
327 } => {
328 cg.addln(&format!(
329 "{}trait {}{}{} {{",
330 visibility.get_rust(),
331 name.get_rust(),
332 generics.get_rust(),
333 if requirements.len() != 0 {
334 String::from(": ")
335 + &requirements
336 .into_iter()
337 .map(TypeExpr::get_rust)
338 .collect::<Vec<_>>()
339 .join("+")
340 } else {
341 String::new()
342 },
343 ));
344 cg.indent += 1;
345
346 for item in items {
347 item.gen_rust(ctx, cg);
348 }
349
350 cg.indent -= 1;
351 cg.addln("}\n");
352 }
353 Self::ClassDecl {
354 visibility,
355 name,
356 generics,
357 inherits,
358 fields,
359 constructor,
360 items,
361 } => {
362 cg.addln(&format!(
364 "{}struct {}{} {{",
365 visibility.get_rust(),
366 name.clone().get_rust(),
367 generics.clone().get_rust()
368 ));
369 cg.indent += 1;
370
371 if let Some(inherits) = inherits {
372 cg.add_indented("pub _super: ");
373 cg.add(&inherits.get_rust());
374 cg.addln(",");
375 }
376
377 for field in fields.clone() {
378 cg.add_indentedln(&field.get_comment());
379 cg.add_indentedln(&field.item.decl.get_rust());
380 }
381
382 cg.indent -= 1;
383 cg.addln("}\n");
384
385 cg.addln(&format!(
387 "impl{} {}{} {{",
388 generics.clone().get_rust(),
389 name.clone().get_rust(),
390 format!(
391 "<{}>",
392 generics
393 .clone()
394 .0
395 .into_iter()
396 .map(|v| Generic::from(v).get_rust())
397 .collect::<Vec<_>>()
398 .join(", ")
399 )
400 ));
401 cg.indent += 1;
402
403 let constructor_comment = constructor.get_comment();
404
405 cg.add_indentedln("#[allow(invalid_value)]");
406 cg.add_indentedln(&constructor_comment);
407
408 (fields, constructor).gen_rust(ctx, cg);
409
410 for item in items.clone() {
411 match item {
412 ClassItem::ImplDecl(_) => {}
413 ClassItem::Method(method) => method.gen_rust(ctx, cg),
414 }
415 }
416
417 cg.indent -= 1;
418 cg.addln("}\n");
419
420 for item in items {
421 match item {
422 ClassItem::ImplDecl(impl_) => {
423 let mut impl_ = impl_.clone();
424
425 impl_.item.trait_ = Some(impl_.item.target);
426 impl_.item.target = TypeExpr(
427 TypeExprKind::Path(Path(vec![name.clone()]), None),
428 Vec::new(),
429 );
430
431 impl_.gen_rust(ctx, cg);
432 }
433 ClassItem::Method(_) => {}
434 }
435 }
436
437 if let Some(inherits) = inherits {
438 cg.add("impl std::ops::Deref for ");
439 cg.add(&name.get_rust());
440
441 cg.addln(" {");
442 cg.indent += 1;
443
444 cg.add_indented("type Target = ");
445 cg.add(&inherits.get_rust());
446 cg.addln(";");
447
448 cg.add_indentedln("fn deref(&self) -> &Self::Target {&self._super}");
449
450 cg.indent -= 1;
451 cg.addln("}");
452
453 cg.add("impl std::ops::DerefMut for ");
456 cg.add(&name.get_rust());
457
458 cg.addln(" {");
459 cg.indent += 1;
460
461 cg.add_indentedln(
462 "fn deref_mut(&mut self) -> &mut Self::Target {&mut self._super}",
463 );
464
465 cg.indent -= 1;
466 cg.addln("}");
467 }
468 }
469 }
470 }
471}