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::FieldAccess(field, generics) => cg.add(&format!(
157 ".{}{}",
158 field.get_rust(),
159 generics
160 .iter()
161 .map(|v| format!("::{}", v.get_rust()))
162 .collect::<String>()
163 )),
164
165 Postfix::Call(args) => {
166 cg.add("(");
167
168 for (i, arg) in args.iter().enumerate() {
169 if i > 0 {
170 cg.add(", ");
171 }
172
173 arg.gen_rust(ctx, cg);
174 }
175
176 cg.add(")");
177 }
178
179 Postfix::MacroCall { inner, delimiter } => {
180 let (open, close) = match delimiter {
181 MacroDelimiter::Paren => ("!(", ")"),
182 MacroDelimiter::Bracket => ("![", "]"),
183 MacroDelimiter::Brace => ("!{", "}"),
184 };
185 cg.add(open);
186 cg.add(inner);
187 cg.add(close);
188 }
189
190 Postfix::StructCall(fields) => {
191 cg.add("{");
192
193 for (name, expr) in fields {
194 cg.add(&name.get_rust());
195 cg.add(": ");
196 expr.gen_rust(ctx, cg);
197 cg.add(",");
198 }
199
200 cg.add("}");
201 }
202
203 Postfix::Index(idx) => {
204 cg.add("[");
205 idx.gen_rust(ctx, cg);
206 cg.add("]");
207 }
208
209 Postfix::As(ty) => {
210 cg.add(" as ");
211 cg.add(&ty.get_rust());
212 }
213
214 Postfix::Try => cg.add("?"),
215
216 Postfix::Assign(cmp, expr) => {
217 cg.add(" ");
218 cg.add(cmp);
219 expr.gen_rust(ctx, cg);
220 }
221 Postfix::Increment => cg.add("+=1"),
222 Postfix::Decrement => cg.add("-=1"),
223 }
224 }
225}
226
227impl GetRust for Generics {
228 fn get_rust(&self) -> String {
229 if self.0.len() == 0 {
230 String::new()
231 } else {
232 format!(
233 "<{}>",
234 self.0
235 .iter()
236 .map(Generic::get_rust)
237 .collect::<Vec<_>>()
238 .join(", ")
239 )
240 }
241 }
242}
243
244impl GetRust for Generic {
245 fn get_rust(&self) -> String {
246 match self {
247 Self::Lifetime(name) => format!("'{}", name.get_rust()),
248 Self::Type(ty) => ty.get_rust(),
249 }
250 }
251}