1use mist_parser::ast::*;
2
3use crate::Context;
4
5use crate::{GenRust, GetRust, RustCodegen};
6
7impl GetRust for ExprPath {
8 fn get_rust(&self) -> String {
9 self.0
10 .iter()
11 .map(ExprPathSegment::get_rust)
12 .collect::<Vec<_>>()
13 .join("::")
14 }
15
16 fn get_rust_ctx(&self, cx: &mut Context) -> String {
17 let mut a = self.clone();
18
19 if let Some(path) = &cx.expr_super {
20 if self.0[0].ident.0 == "super" && self.0.len() == 1 {
21 a.0[0].ident.0 = String::from("self._super");
22 } else if self.0[0].ident.0 == "Super" {
23 a.0[0] = path.0[0].clone();
24 }
25 }
26
27 a.get_rust()
28 }
29}
30
31impl GetRust for ExprPathSegment {
32 fn get_rust(&self) -> String {
33 format!(
34 "{}{}",
35 self.ident.get_rust(),
36 self.generics
37 .as_ref()
38 .map(|v| format!("::{}", v.get_rust()))
39 .unwrap_or_default()
40 )
41 }
42}
43
44impl GenRust for Literal {
45 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
46 match self {
47 Self::Int(n) => cg.add(&n.to_string()),
48 Self::Float(n) => cg.add(&format!("{n:?}")),
49 Self::Bool(b) => cg.add(&b.to_string()),
50 Self::String(s) => cg.add(&format!("\"{s}\"")),
51
52 Self::Tuple(values) => {
53 cg.add("(");
54
55 for (i, val) in values.iter().enumerate() {
56 if i > 0 {
57 cg.add(", ");
58 }
59
60 val.gen_rust(ctx, cg);
61 }
62
63 cg.add(")");
64 }
65 }
66 }
67}
68
69impl GenRust for Expression {
70 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
71 let ensure_semicolon = if ctx.expr_ensure_semicolon {
72 ctx.expr_ensure_semicolon = false;
73
74 true
75 } else {
76 false
77 };
78
79 match self {
80 Expression::Path(path) => cg.add(&path.get_rust_ctx(ctx)),
81 Expression::Literal(literal) => literal.gen_rust(ctx, cg),
82 Expression::Statement(stmt) => stmt.gen_rust(ctx, cg),
83 Expression::Array(values) => {
84 cg.add("[");
85
86 for (i, val) in values.iter().enumerate() {
87 if i > 0 {
88 cg.add(", ");
89 }
90
91 val.gen_rust(ctx, cg);
92 }
93
94 cg.add("]");
95 }
96 Expression::ArrayRepeat(value, repeat) => {
97 cg.add("[");
98 value.gen_rust(ctx, cg);
99 cg.add("; ");
100 repeat.gen_rust(ctx, cg);
101 cg.add("]");
102 }
103 Expression::Fix {
104 initial,
105 prefixes,
106 postfixes,
107 } => {
108 prefixes.gen_rust(ctx, cg);
109 initial.gen_rust(ctx, cg);
110 for postfix in postfixes {
111 postfix.gen_rust(ctx, cg);
112 }
113 }
114
115 Expression::Binary { lhs, op, rhs } => {
116 if op == "->" {
117 cg.add("unsafe { std::ptr::write(&mut ");
118 lhs.gen_rust(ctx, cg);
119 cg.add(", ");
120 rhs.gen_rust(ctx, cg);
121 cg.add(") }");
122 } else {
123 lhs.gen_rust(ctx, cg);
124 cg.add(op);
125 rhs.gen_rust(ctx, cg);
126 }
127 }
128
129 Expression::Closure {
130 return_type,
131 params,
132 body,
133 } => {
134 cg.add("|");
135 for (i, arg) in params.iter().enumerate() {
136 if i > 0 {
137 cg.add(", ");
138 }
139
140 arg.gen_rust(ctx, cg);
141 }
142 cg.add("| ");
143
144 if let Some(ty) = return_type {
145 cg.add("-> ");
146 cg.add(&ty.get_rust());
147 cg.add(" ");
148
149 cg.ensure_brackets_expr(ctx, body);
150 } else {
151 body.gen_rust(ctx, cg);
152 }
153 }
154 }
155
156 if ensure_semicolon {
157 ctx.expr_ensure_semicolon = true;
158
159 if !self.is_block() {
160 cg.add(";");
161 }
162 }
163 }
164}
165
166impl GenRust for Prefix {
167 fn gen_rust(&self, _ctx: &mut Context, cg: &mut RustCodegen) {
168 match self {
169 Self::Deref => cg.add("*"),
170 Self::Ref => cg.add("&"),
171 Self::RefMut => cg.add("&mut "),
172 Self::Not => cg.add("!"),
173 Self::Neg => cg.add("-"),
174 }
175 }
176}
177
178impl GenRust for Vec<Prefix> {
179 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
180 for prefix in self {
181 prefix.gen_rust(ctx, cg);
182 }
183 }
184}
185
186impl GenRust for Postfix {
187 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
188 match self {
189 Postfix::TupleFieldAccess(field, generics) => cg.add(&format!(
190 ".{}{}",
191 field,
192 generics
193 .iter()
194 .map(|v| format!("::{}", v.get_rust()))
195 .collect::<String>()
196 )),
197 Postfix::FieldAccess(field, generics) => cg.add(&format!(
198 ".{}{}",
199 field.get_rust(),
200 generics
201 .iter()
202 .map(|v| format!("::{}", v.get_rust()))
203 .collect::<String>()
204 )),
205
206 Postfix::Call(args) => {
207 cg.add("(");
208
209 for (i, arg) in args.iter().enumerate() {
210 if i > 0 {
211 cg.add(", ");
212 }
213
214 arg.gen_rust(ctx, cg);
215 }
216
217 cg.add(")");
218 }
219
220 Postfix::MacroCall { inner, delimiter } => {
221 let (open, close) = match delimiter {
222 MacroDelimiter::Paren => ("!(", ")"),
223 MacroDelimiter::Bracket => ("![", "]"),
224 MacroDelimiter::Brace => ("!{", "}"),
225 };
226 cg.add(open);
227 cg.add(inner);
228 cg.add(close);
229 }
230
231 Postfix::StructCall(fields) => {
232 cg.add("{");
233
234 for (name, expr) in fields {
235 cg.add(&name.get_rust());
236 if let Some(expr) = expr {
237 cg.add(": ");
238 expr.gen_rust(ctx, cg);
239 }
240 cg.add(",");
241 }
242
243 cg.add("}");
244 }
245
246 Postfix::Index(idx) => {
247 cg.add("[");
248 idx.gen_rust(ctx, cg);
249 cg.add("]");
250 }
251
252 Postfix::As(ty) => {
253 cg.add(" as ");
254 cg.add(&ty.get_rust());
255 }
256
257 Postfix::Try => cg.add("?"),
258
259 Postfix::Assign(cmp, expr) => {
260 cg.add(" ");
261 cg.add(cmp);
262 expr.gen_rust(ctx, cg);
263 }
264 Postfix::Increment => cg.add("+=1"),
265 Postfix::Decrement => cg.add("-=1"),
266 }
267 }
268}
269
270impl GetRust for Generics {
271 fn get_rust(&self) -> String {
272 if self.0.len() == 0 {
273 String::new()
274 } else {
275 format!(
276 "<{}>",
277 self.0
278 .iter()
279 .map(Generic::get_rust)
280 .collect::<Vec<_>>()
281 .join(", ")
282 )
283 }
284 }
285}
286
287impl GetRust for Generic {
288 fn get_rust(&self) -> String {
289 match self {
290 Self::Lifetime(name) => format!("'{}", name.get_rust()),
291 Self::Type(ty) => ty.get_rust(),
292 }
293 }
294}