Skip to content

Commit d5d7f24

Browse files
chqrliebvdberg
authored andcommitted
C generator: fix code generation for if stmt and multi-decl
* wrap `if` statement with declaration in condition in a block * generate single statement for multi-declarations * add tests
1 parent 007ff92 commit d5d7f24

File tree

4 files changed

+106
-16
lines changed

4 files changed

+106
-16
lines changed

generator/c/c2i_generator_stmt.c2

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,18 +187,21 @@ fn void Generator.emitStmt(Generator* gen, ast.Stmt* s, u32 indent, bool newline
187187
VarDecl* vd = ds.getDecl(i);
188188
Decl* d = cast<Decl*>(vd);
189189

190-
// TODO: combine into a single statement
191190
//if (vd.hasLocalQualifier()) out.add("local ");
192-
gen.emitTypeRef(vd.getTypeRef());
191+
if (i == 0) {
192+
gen.emitTypeRef(vd.getTypeRef());
193+
} else {
194+
out.add1(',');
195+
}
193196
out.space();
194197
out.add(d.getName());
195198
const Expr* ie = vd.getInit();
196199
if (ie) {
197200
out.add(" = ");
198201
gen.emitExpr(ie);
199202
}
200-
if (newline) out.add(";\n");
201203
}
204+
if (newline) out.add(";\n");
202205
break;
203206
case Asm:
204207
//gen.emitAsmStmt(cast<AsmStmt*>(s), indent);

generator/c/c_generator_stmt.c2

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,22 @@ import ast local;
1919
import source_mgr;
2020
import string_buffer;
2121

22-
fn void Generator.emitVarDecl(Generator* gen, VarDecl* vd, string_buffer.Buf* out, bool emit_init) {
22+
fn void Generator.emitVarDecl(Generator* gen, VarDecl* vd, string_buffer.Buf* out, bool emit_init, bool first) {
2323
Decl* d = cast<Decl*>(vd);
24-
if (vd.hasLocalQualifier()) out.add("static ");
25-
gen.emitTypePre(out, d.getType());
24+
if (first) {
25+
if (vd.hasLocalQualifier()) out.add("static ");
26+
gen.emitTypePre(out, d.getType());
27+
} else {
28+
out.add1(',');
29+
}
2630
out.space();
2731
out.add(d.getName());
2832
gen.emitTypePost(out, d.getType());
2933
d.setGenerated();
3034
Expr* ie = vd.getInit();
3135
if (ie && emit_init) {
3236
if (vd.hasInitCall()) {
37+
assert(first);
3338
out.add("; ");
3439
} else {
3540
out.add(" = ");
@@ -66,8 +71,10 @@ fn void Generator.emitStmt(Generator* gen, Stmt* s, u32 indent, bool newline) {
6671
Stmt* cond = i.getCond();
6772
bool is_decl = cond.isDecl();
6873
if (is_decl) {
74+
out.add("{\n");
75+
indent++;
6976
// TODO leave out init part
70-
gen.emitStmt(cond, 0, true);
77+
gen.emitStmt(cond, indent, true);
7178
out.indent(indent);
7279
out.add("if (");
7380
DeclStmt* ds = cast<DeclStmt*>(cond);
@@ -100,6 +107,11 @@ fn void Generator.emitStmt(Generator* gen, Stmt* s, u32 indent, bool newline) {
100107
}
101108
}
102109
out.newline();
110+
if (is_decl) {
111+
indent--;
112+
out.indent(indent);
113+
out.add("}\n");
114+
}
103115
break;
104116
case While:
105117
WhileStmt* w = cast<WhileStmt*>(s);
@@ -111,7 +123,7 @@ fn void Generator.emitStmt(Generator* gen, Stmt* s, u32 indent, bool newline) {
111123
DeclStmt* ds = cast<DeclStmt*>(cond);
112124
VarDecl* vd = ds.getDecl(0);
113125
out.indent(indent);
114-
gen.emitVarDecl(vd, out, false);
126+
gen.emitVarDecl(vd, out, false, true);
115127
out.add(";\n");
116128
out.indent(indent);
117129
out.add("while (");
@@ -215,11 +227,13 @@ fn void Generator.emitStmt(Generator* gen, Stmt* s, u32 indent, bool newline) {
215227
case Decl:
216228
DeclStmt* ds = cast<DeclStmt*>(s);
217229
u32 count = ds.getDeclCount();
230+
bool first = true;
218231
for (u32 i = 0; i < count; i++) {
219232
VarDecl* vd = ds.getDecl(i);
220-
gen.emitVarDecl(vd, out, true);
221-
if (newline) out.add(";\n");
233+
gen.emitVarDecl(vd, out, true, first);
234+
first = false;
222235
}
236+
if (newline) out.add(";\n");
223237
break;
224238
case Asm:
225239
gen.emitAsmStmt(cast<AsmStmt*>(s), indent);

test/c_generator/stmts/if_stmt_expr.c2t

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ public fn i32 main(i32 argc, const char** argv) {
99
i32 a = 0;
1010
if (a) {}
1111

12-
if (i32 b = 10) {
13-
14-
}
12+
if (a)
13+
if (i32 b = 10)
14+
return 0;
15+
else
16+
return 1;
1517

1618
if (true) {
17-
19+
return 2;
1820
}
1921

2022
return 0;
@@ -28,11 +30,14 @@ int32_t main(int32_t argc, const char** argv)
2830
if (a) {
2931
}
3032

31-
int32_t b = 10;
32-
if (b) {
33+
if (a) {
34+
int32_t b = 10;
35+
if (b) return 0;
36+
else return 1;
3337
}
3438

3539
if (true) {
40+
return 2;
3641
}
3742

3843
return 0;

test/c_generator/stmts/multi_def.c2t

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// @recipe bin
2+
$warnings no-unused
3+
$backend c
4+
5+
// @file{file1}
6+
module test;
7+
8+
type Point struct {
9+
i32 x, y;
10+
}
11+
12+
fn void Point.print(const Point* p) {
13+
//printf("{ %d, %d }\n", p.x, p.y);
14+
}
15+
16+
fn void test1(i32 i) {}
17+
18+
public fn i32 main() {
19+
i32 x = 1, y = 2;
20+
21+
Point p1 = { 1, 2 }, p2 = { 3, 4 };
22+
23+
if (x > y)
24+
if (i32 z = 1)
25+
p1.print();
26+
else
27+
p2.print();
28+
29+
for (i32 i = 0, n = 32; i < n; i++)
30+
test1(i);
31+
32+
return 0;
33+
}
34+
35+
// @expect{atleast, cgen/build.c}
36+
37+
typedef struct test_Point_ test_Point;
38+
39+
struct test_Point_ {
40+
int32_t x;
41+
int32_t y;
42+
};
43+
44+
static void test_Point_print(const test_Point* p);
45+
static void test_test1(int32_t i);
46+
int32_t main(void);
47+
48+
static void test_Point_print(const test_Point* p)
49+
{
50+
}
51+
52+
static void test_test1(int32_t i)
53+
{
54+
}
55+
56+
int32_t main(void)
57+
{
58+
int32_t x = 1, y = 2;
59+
test_Point p1 = { 1, 2 }, p2 = { 3, 4 };
60+
if ((x > y)) {
61+
int32_t z = 1;
62+
if (z) test_Point_print(&p1);
63+
else test_Point_print(&p2);
64+
}
65+
66+
for (int32_t i = 0, n = 32; (i < n); i++) test_test1(i);
67+
return 0;
68+
}

0 commit comments

Comments
 (0)