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