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