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 self.1.item.params.gen_rust(ctx, cg);
179
180 cg.addln(") -> Self {");
181 cg.indent += 1;
182
183 cg.add_indentedln("let mut this: Self = unsafe { std::mem::MaybeUninit::<Self>::zeroed().assume_init() };");
184
185 for field in self.0 {
186 let comment = field.get_comment();
187
188 if let Some(init) = &field.item.init {
189 cg.add_indentedln(&comment);
190
191 cg.add_indentedln(&format!("this.{} = ", field.item.decl.name.get_rust()));
192
193 init.gen_rust(ctx, cg);
194 }
195 }
196
197 cg.add_indented(&format!("this.constructor("));
198
199 for (i, param) in self
200 .1
201 .item
202 .params
203 .0
204 .iter()
205 .map(|v| expr_pattern(&v.name))
206 .enumerate()
207 {
208 if i > 0 {
209 cg.add(", ");
210 }
211
212 ctx.expr_ensure_semicolon = false;
213 param.gen_rust(ctx, cg);
214 }
215
216 cg.addln(");");
217
218 cg.add_indentedln("this");
219
220 cg.indent -= 1;
221 cg.add_indentedln("}\n");
222
223 let mut constructor_params = vec![VarDecl {
224 name: Pattern::Path(false, Path(vec![Identifier(String::from("self"))])),
225 type_: Some(TypeExpr(
226 TypeExprKind::Path(Path(vec![Identifier(String::from("Self"))])),
227 vec![TypePostfix::RefMut],
228 )),
229 }];
230
231 constructor_params.append(&mut self.1.item.params.0.clone());
232
233 Spanned {
234 line: self.1.line,
235 column: self.1.column,
236 item: FunctionDecl {
237 visibility: self.1.item.visibility.clone(),
238 name: Identifier(String::from("constructor")),
239 generics: self.1.item.generics.clone(),
240 params: ParamList(constructor_params),
241 return_type: TypeExpr::no_px(TypeExprKind::Tuple(Vec::new())),
242 body: Some(self.1.item.body.clone()),
243 },
244 }
245 .gen_rust(ctx, cg);
246 }
247}
248
249pub fn expr_pattern(pat: &Pattern) -> Expression {
250 match pat {
251 Pattern::Literal(v) => Expression::Literal(v.clone()),
252 Pattern::Path(_, v) => Expression::Path(v.clone().into()),
253 Pattern::Tuple(items) => Expression::Literal(Literal::Tuple(
254 items.iter().map(|v| expr_pattern(&v)).collect(),
255 )),
256 Pattern::NamedTuple(path, items) => Expression::Fix {
257 initial: Box::new(Expression::Path(path.clone().into())),
258 prefixes: Vec::new(),
259 postfixes: vec![Postfix::Call(
260 items.iter().map(|v| expr_pattern(&v)).collect(),
261 )],
262 },
263 Pattern::Struct(_, _) => unimplemented!(),
264 }
265}
266
267impl GenRust for TopLevelKind {
268 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
269 match self {
270 Self::ModAttribute => {}
271 Self::Import(vis, path) => {
272 cg.addln(&format!("{}use {};", vis.get_rust(), path.get_rust()))
273 }
274 Self::Mod(vis, id) => cg.addln(&format!("{}mod {};", vis.get_rust(), id.get_rust())),
275 Self::FunctionDecl(decl) => decl.gen_rust(ctx, cg),
276 Self::ImplDecl(impl_) => impl_.gen_rust(ctx, cg),
277 Self::StructDecl {
278 visibility,
279 name,
280 generics,
281 fields,
282 } => {
283 cg.addln(&format!(
284 "{}struct {}{} {{",
285 visibility.get_rust(),
286 name.get_rust(),
287 generics.get_rust()
288 ));
289 cg.indent += 1;
290
291 for field in fields {
292 cg.add_indentedln(&field.get_rust());
293 }
294
295 cg.indent -= 1;
296 cg.addln("}\n");
297 }
298 Self::EnumDecl {
299 visibility,
300 name,
301 generics,
302 fields,
303 } => {
304 cg.addln(&format!(
305 "{}enum {}{} {{",
306 visibility.get_rust(),
307 name.get_rust(),
308 generics.get_rust()
309 ));
310 cg.indent += 1;
311
312 for field in fields {
313 cg.add_indentedln(&(field.get_rust() + ","));
314 }
315
316 cg.indent -= 1;
317 cg.addln("}\n");
318 }
319 Self::TraitDecl {
320 visibility,
321 name,
322 generics,
323 requirements,
324 items,
325 } => {
326 cg.addln(&format!(
327 "{}trait {}{}{} {{",
328 visibility.get_rust(),
329 name.get_rust(),
330 generics.get_rust(),
331 if requirements.len() != 0 {
332 String::from(": ")
333 + &requirements
334 .into_iter()
335 .map(TypeExpr::get_rust)
336 .collect::<Vec<_>>()
337 .join("+")
338 } else {
339 String::new()
340 },
341 ));
342 cg.indent += 1;
343
344 for item in items {
345 item.gen_rust(ctx, cg);
346 }
347
348 cg.indent -= 1;
349 cg.addln("}\n");
350 }
351 Self::ClassDecl {
352 visibility,
353 name,
354 generics,
355 inherits,
356 fields,
357 constructor,
358 items,
359 } => {
360 cg.addln(&format!(
362 "{}struct {}{} {{",
363 visibility.get_rust(),
364 name.clone().get_rust(),
365 generics.clone().get_rust()
366 ));
367 cg.indent += 1;
368
369 if let Some(inherits) = inherits {
370 cg.add_indented("pub _super: ");
371 cg.add(&inherits.get_rust());
372 cg.addln(",");
373 }
374
375 for field in fields.clone() {
376 cg.add_indentedln(&field.get_comment());
377 cg.add_indentedln(&field.item.decl.get_rust());
378 }
379
380 cg.indent -= 1;
381 cg.addln("}\n");
382
383 cg.addln(&format!(
385 "impl{} {}{} {{",
386 generics.clone().get_rust(),
387 name.clone().get_rust(),
388 format!(
389 "<{}>",
390 generics
391 .clone()
392 .0
393 .into_iter()
394 .map(|v| Generic::from(v).get_rust())
395 .collect::<Vec<_>>()
396 .join(", ")
397 )
398 ));
399 cg.indent += 1;
400
401 let constructor_comment = constructor.get_comment();
402
403 cg.add_indentedln("#[allow(invalid_value)]");
404 cg.add_indentedln(&constructor_comment);
405
406 (fields, constructor).gen_rust(ctx, cg);
407
408 for item in items.clone() {
409 match item {
410 ClassItem::ImplDecl(_) => {}
411 ClassItem::Method(method) => method.gen_rust(ctx, cg),
412 }
413 }
414
415 cg.indent -= 1;
416 cg.addln("}\n");
417
418 for item in items {
419 match item {
420 ClassItem::ImplDecl(impl_) => {
421 let mut impl_ = impl_.clone();
422
423 impl_.item.trait_ = Some(impl_.item.target);
424 impl_.item.target =
425 TypeExpr(TypeExprKind::Path(Path(vec![name.clone()])), Vec::new());
426
427 impl_.gen_rust(ctx, cg);
428 }
429 ClassItem::Method(_) => {}
430 }
431 }
432
433 if let Some(inherits) = inherits {
434 cg.add("impl std::ops::Deref for ");
435 cg.add(&name.get_rust());
436
437 cg.addln(" {");
438 cg.indent += 1;
439
440 cg.add_indented("type Target = ");
441 cg.add(&inherits.get_rust());
442 cg.addln(";");
443
444 cg.add_indentedln("fn deref(&self) -> &Self::Target {&self._super}");
445
446 cg.indent -= 1;
447 cg.addln("}");
448
449 cg.add("impl std::ops::DerefMut for ");
452 cg.add(&name.get_rust());
453
454 cg.addln(" {");
455 cg.indent += 1;
456
457 cg.add_indentedln(
458 "fn deref_mut(&mut self) -> &mut Self::Target {&mut self._super}",
459 );
460
461 cg.indent -= 1;
462 cg.addln("}");
463 }
464 }
465 }
466 }
467}