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