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 initial.condition.gen_rust(ctx, cg);
94 cg.add(" ");
95 cg.ensure_brackets_body(ctx, &initial.body);
96
97 for else_if_branch in else_if {
98 cg.add("else if");
99 else_if_branch.condition.gen_rust(ctx, cg);
100 cg.add(" ");
101 cg.ensure_brackets_body(ctx, &else_if_branch.body);
102 }
103
104 if let Some(else_br) = else_branch {
105 cg.add(" else ");
106 cg.ensure_brackets_body(ctx, else_br);
107 }
108 }
109
110 Statement::While(StatementBranch { condition, body }) => {
111 cg.add("while ");
112 condition.gen_rust(ctx, cg);
113 cg.add(" ");
114 cg.ensure_brackets_body(ctx, body);
115 }
116
117 Statement::Loop(body) => {
118 cg.add("loop ");
119 cg.ensure_brackets_body(ctx, body);
120 }
121
122 Statement::CStyleFor {
123 init,
124 condition,
125 update,
126 body,
127 } => {
128 cg.addln("{");
129 cg.indent += 1;
130
131 ctx.expr_ensure_semicolon = true;
132
133 cg.add_indented("");
134
135 init.gen_rust(ctx, cg);
136
137 cg.addln("");
138
139 cg.add_indented("while ");
140
141 ctx.expr_ensure_semicolon = false;
142 condition.gen_rust(ctx, cg);
143
144 cg.add(" ");
145
146 cg.add("{");
147 cg.indent += 1;
148
149 ctx.expr_ensure_semicolon = true;
150
151 body.gen_rust(ctx, cg);
152
153 update.gen_rust(ctx, cg);
154
155 cg.addln("");
156
157 cg.indent -= 1;
158 cg.add_indentedln("}");
159
160 cg.indent -= 1;
161 cg.add_indented("}");
162 }
163
164 Statement::For {
165 pattern,
166 iterator,
167 body,
168 } => {
169 cg.add("for ");
170 pattern.gen_rust(ctx, cg);
171 cg.add(" in ");
172 iterator.gen_rust(ctx, cg);
173 cg.ensure_brackets_body(ctx, body);
174 }
175
176 Statement::Return(expr) => {
177 cg.add("return ");
178 if let Some(expr) = expr {
179 expr.gen_rust(ctx, cg);
180 }
181 }
182
183 Statement::Break => cg.add_indentedln("break"),
184 Statement::Continue => cg.add_indentedln("continue"),
185 }
186 }
187}
188
189impl GenRust for VarDecl {
190 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
191 self.name.gen_rust(ctx, cg);
192
193 cg.add(
194 &self
195 .type_
196 .as_ref()
197 .map(|t| format!(": {}", t.get_rust()))
198 .unwrap_or_default(),
199 );
200 }
201}