mist_codegen/
statement.rs1use mist_parser::ast::*;
2
3use crate::{Context, get_mutable};
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 (pat, body) in match_items {
63 for (i, p) in pat.iter().enumerate() {
64 cg.addln("");
65 cg.add_indented("");
66 if i > 0 {
67 cg.add(" | ");
68 }
69
70 p.gen_rust(ctx, cg);
71 }
72
73 cg.add(" => ");
74
75 cg.ensure_brackets_expr(ctx, body);
76 }
77
78 cg.indent -= 1;
79 cg.addln("");
80 cg.add_indented("}");
81 }
82
83 Statement::If {
84 initial,
85 else_if,
86 else_branch,
87 } => {
88 cg.add("if ");
89 initial.condition.gen_rust(ctx, cg);
90 cg.add(" ");
91 cg.ensure_brackets_body(ctx, &initial.body);
92
93 for else_if_branch in else_if {
94 cg.add("else if");
95 else_if_branch.condition.gen_rust(ctx, cg);
96 cg.add(" ");
97 cg.ensure_brackets_body(ctx, &else_if_branch.body);
98 }
99
100 if let Some(else_br) = else_branch {
101 cg.add(" else ");
102 cg.ensure_brackets_body(ctx, else_br);
103 }
104 }
105
106 Statement::While(StatementBranch { condition, body }) => {
107 cg.add("while ");
108 condition.gen_rust(ctx, cg);
109 cg.add(" ");
110 cg.ensure_brackets_body(ctx, body);
111 }
112
113 Statement::Loop(body) => {
114 cg.add("loop ");
115 cg.ensure_brackets_body(ctx, body);
116 }
117
118 Statement::CStyleFor {
119 init,
120 condition,
121 update,
122 body,
123 } => {
124 cg.addln("{");
125 cg.indent += 1;
126
127 ctx.expr_ensure_semicolon = true;
128
129 cg.add_indented("");
130
131 init.gen_rust(ctx, cg);
132
133 cg.addln("");
134
135 cg.add_indented("while ");
136
137 ctx.expr_ensure_semicolon = false;
138 condition.gen_rust(ctx, cg);
139
140 cg.add(" ");
141
142 cg.add("{");
143 cg.indent += 1;
144
145 ctx.expr_ensure_semicolon = true;
146
147 body.gen_rust(ctx, cg);
148
149 update.gen_rust(ctx, cg);
150
151 cg.addln("");
152
153 cg.indent -= 1;
154 cg.add_indentedln("}");
155
156 cg.indent -= 1;
157 cg.add_indented("}");
158 }
159
160 Statement::For {
161 mutable,
162 pattern,
163 iterator,
164 body,
165 } => {
166 cg.add("for ");
167 cg.add(&get_mutable(*mutable));
168 pattern.gen_rust(ctx, cg);
169 cg.add(" in ");
170 iterator.gen_rust(ctx, cg);
171 cg.ensure_brackets_body(ctx, body);
172 }
173
174 Statement::Return(expr) => {
175 cg.add("return ");
176 if let Some(expr) = expr {
177 expr.gen_rust(ctx, cg);
178 }
179 }
180
181 Statement::Break => cg.add_indentedln("break"),
182 Statement::Continue => cg.add_indentedln("continue"),
183 }
184 }
185}
186
187impl GenRust for VarDecl {
188 fn gen_rust(&self, ctx: &mut Context, cg: &mut RustCodegen) {
189 cg.add(&get_mutable(self.mutable));
190
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}