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