mist_codegen/
statement.rs1use mist_parser::ast::*;
2
3use crate::Context;
4
5use crate::{GenRust, GetRust, RustCodegen};
6
7impl GenRust for Block {
8 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
9 if self.is_unsafe {
10 cg.add("unsafe ");
11 }
12
13 cg.addln("{");
14 cg.indent += 1;
15
16 for stmt in &self.statements {
17 ctx.expr_ensure_semicolon = true;
18 stmt.gen_rust(ctx, cg);
19 cg.addln("");
20 }
21
22 if let Some(soft_return) = &self.soft_return {
23 ctx.expr_ensure_semicolon = false;
24 soft_return.gen_rust(ctx, cg);
25 cg.addln("");
26 }
27
28 cg.indent -= 1;
29 cg.add_indented("}");
30 }
31}
32
33impl GenRust for StatementBody {
34 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
35 match self {
36 Self::Expression(expr) => expr.gen_rust(ctx, cg),
37 Self::Statement(stmt) => {
38 ctx.expr_ensure_semicolon = true;
39 stmt.gen_rust(ctx, cg);
40 }
41 }
42 }
43}
44
45impl GenRust for Statement {
46 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
47 match self {
48 Statement::Block(block) => block.gen_rust(ctx, cg),
49
50 Statement::VarDecl(VarDeclStmt { decl, init }) => {
51 cg.add("let ");
52 decl.gen_rust(ctx, cg);
53
54 if let Some(init) = init {
55 cg.add(" = ");
56 init.gen_rust(ctx, cg);
57 }
58 }
59
60 Statement::Match(expr, match_items) => {
61 cg.add("match ");
62 expr.gen_rust(ctx, cg);
63 cg.add(" {");
64 cg.indent += 1;
65
66 for match_item in match_items {
67 cg.add_indentedln(&match_item.get_comment());
68
69 let MatchItem(pat, body) = &match_item.item;
70
71 for (i, p) in pat.iter().enumerate() {
72 cg.addln("");
73 cg.add_indented("");
74 if i > 0 {
75 cg.add(" | ");
76 }
77
78 p.gen_rust(ctx, cg);
79 }
80
81 cg.add(" => ");
82
83 cg.ensure_brackets_expr(ctx, body);
84 }
85
86 cg.indent -= 1;
87 cg.addln("");
88 cg.add_indented("}");
89 }
90
91 Statement::If {
92 initial,
93 else_if,
94 else_branch,
95 } => {
96 cg.add("if ");
97 ctx.expr_ensure_semicolon = false;
98 initial.condition.gen_rust(ctx, cg);
99 cg.add(" ");
100 cg.ensure_brackets_body(ctx, &initial.body);
101
102 for else_if_branch in else_if {
103 cg.add(" else if ");
104 ctx.expr_ensure_semicolon = false;
105 else_if_branch.condition.gen_rust(ctx, cg);
106 cg.add(" ");
107 cg.ensure_brackets_body(ctx, &else_if_branch.body);
108 }
109
110 if let Some(else_br) = else_branch {
111 cg.add(" else ");
112 cg.ensure_brackets_body(ctx, else_br);
113 }
114 }
115
116 Statement::While(StatementBranch { condition, body }) => {
117 cg.add("while ");
118 condition.gen_rust(ctx, cg);
119 cg.add(" ");
120 cg.ensure_brackets_body(ctx, body);
121 }
122
123 Statement::Loop(body) => {
124 cg.add("loop ");
125 cg.ensure_brackets_body(ctx, body);
126 }
127
128 Statement::CStyleFor {
129 init,
130 condition,
131 update,
132 body,
133 } => {
134 cg.addln("{");
135 cg.indent += 1;
136
137 ctx.expr_ensure_semicolon = true;
138
139 cg.add_indented("");
140
141 init.gen_rust(ctx, cg);
142
143 cg.addln("");
144
145 cg.add_indented("while ");
146
147 ctx.expr_ensure_semicolon = false;
148 condition.gen_rust(ctx, cg);
149
150 cg.add(" ");
151
152 cg.add("{");
153 cg.indent += 1;
154
155 ctx.expr_ensure_semicolon = true;
156
157 body.gen_rust(ctx, cg);
158
159 update.gen_rust(ctx, cg);
160
161 cg.addln("");
162
163 cg.indent -= 1;
164 cg.add_indentedln("}");
165
166 cg.indent -= 1;
167 cg.add_indented("}");
168 }
169
170 Statement::For {
171 pattern,
172 iterator,
173 body,
174 } => {
175 cg.add("for ");
176 pattern.gen_rust(ctx, cg);
177 cg.add(" in ");
178 iterator.gen_rust(ctx, cg);
179 cg.ensure_brackets_body(ctx, body);
180 }
181
182 Statement::Return(expr) => {
183 cg.add("return ");
184 if let Some(expr) = expr {
185 expr.gen_rust(ctx, cg);
186 }
187 }
188
189 Statement::Break => cg.add_indentedln("break"),
190 Statement::Continue => cg.add_indentedln("continue"),
191 }
192 }
193}
194
195impl GenRust for VarDecl {
196 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
197 self.name.gen_rust(ctx, cg);
198
199 cg.add(
200 &self
201 .type_
202 .as_ref()
203 .map(|t| format!(": {}", t.get_rust()))
204 .unwrap_or_default(),
205 );
206 }
207}