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