1use mist_parser::ast::*;
2
3use crate::{Context, class_decl};
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 TopLevelKind {
174 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
175 match self {
176 Self::ModAttribute => {}
177 Self::Import(vis, path) => {
178 cg.addln(&format!("{}use {};", vis.get_rust(), path.get_rust()))
179 }
180 Self::Mod(vis, id) => cg.addln(&format!("{}mod {};", vis.get_rust(), id.get_rust())),
181 Self::FunctionDecl(decl) => decl.gen_rust(ctx, cg),
182 Self::ImplDecl(impl_) => impl_.gen_rust(ctx, cg),
183 Self::StructDecl {
184 visibility,
185 name,
186 generics,
187 fields,
188 } => {
189 cg.addln(&format!(
190 "{}struct {}{} {{",
191 visibility.get_rust(),
192 name.get_rust(),
193 generics.get_rust()
194 ));
195 cg.indent += 1;
196
197 for field in fields {
198 cg.add_indentedln(&field.get_rust());
199 }
200
201 cg.indent -= 1;
202 cg.addln("}\n");
203 }
204 Self::EnumDecl {
205 visibility,
206 name,
207 generics,
208 fields,
209 } => {
210 cg.addln(&format!(
211 "{}enum {}{} {{",
212 visibility.get_rust(),
213 name.get_rust(),
214 generics.get_rust()
215 ));
216 cg.indent += 1;
217
218 for field in fields {
219 cg.add_indentedln(&(field.get_rust() + ","));
220 }
221
222 cg.indent -= 1;
223 cg.addln("}\n");
224 }
225 Self::TraitDecl {
226 visibility,
227 name,
228 generics,
229 requirements,
230 items,
231 } => {
232 cg.addln(&format!(
233 "{}trait {}{}{} {{",
234 visibility.get_rust(),
235 name.get_rust(),
236 generics.get_rust(),
237 if requirements.len() != 0 {
238 String::from(": ")
239 + &requirements
240 .into_iter()
241 .map(TypeExpr::get_rust)
242 .collect::<Vec<_>>()
243 .join("+")
244 } else {
245 String::new()
246 },
247 ));
248 cg.indent += 1;
249
250 for item in items {
251 item.gen_rust(ctx, cg);
252 }
253
254 cg.indent -= 1;
255 cg.addln("}\n");
256 }
257 Self::ClassDecl {
258 visibility,
259 name,
260 generics,
261 inherits,
262 fields,
263 constructor,
264 items,
265 } => class_decl::class_decl(
266 ctx,
267 cg,
268 visibility,
269 name,
270 generics,
271 inherits,
272 fields,
273 constructor,
274 items,
275 ),
276 }
277 }
278}