Skip to content

Commit 8f844bd

Browse files
committed
Finish end-to-end compound statements and chapter 7
1 parent 2218889 commit 8f844bd

2 files changed

Lines changed: 46 additions & 16 deletions

File tree

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,22 @@ The [tests](https://github.com/nlsandler/writing-a-c-compiler-tests/) provided w
88

99
## Current status
1010

11-
This compiler is complete through Chapter 6 of the book meaning it compiles programs of the form
11+
This compiler is complete through Chapter 7 of the book meaning it compiles programs of the form
1212

1313
```c
1414
int main(void) {
1515
int x = 3;
1616
int y = 2;
17-
if (y)
18-
return x > y ? 1 : 0;
19-
else
17+
if (y) {
18+
int z = 3;
19+
return x > y+z ? 1 : 0;
20+
} else {
2021
return ~(-4) * (x + 12) || y > 12;
22+
}
2123
}
2224
```
2325
24-
for any combination of `~, -`, binary ops `+, -, *, /, %, <, <=, >, >=, ==, !=, !, &&, ||`, parentheses, `int` variables, if/else, conditional expressions (`?:`), and any integer constants.
26+
for any combination of `~, -`, binary ops `+, -, *, /, %, <, <=, >, >=, ==, !=, !, &&, ||`, parentheses, `int` variables, if/else, conditional expressions (`?:`), blocks in `{}` with nested declarations, and any integer constants.
2527
2628
See the [current grammar](#current-grammar) section for full details of what is supported.
2729

src/ast_to_tacky.rs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,8 @@ impl AstToTacky {
2626
}
2727

2828
fn convert_function(&mut self, func: &ast::Function) -> tacky::Function {
29-
// let mut instructions: InstructionVec = func
30-
// .body
31-
// .iter()
32-
// .flat_map(|block| self.convert_block_item(block))
33-
// .collect();
3429
let mut instructions: InstructionVec = Vec::new();
35-
func
36-
.body
37-
.items
38-
.iter()
39-
.for_each(|block| self.convert_block_item(block, &mut instructions));
30+
self.convert_block(&func.body, &mut &mut instructions);
4031

4132
// Tack (ha) on a return statement to handle cases
4233
// when main omits it or for void return. If func already
@@ -53,6 +44,13 @@ impl AstToTacky {
5344
function
5445
}
5546

47+
fn convert_block(&mut self, block: &ast::Block, instructions: &mut InstructionVec) {
48+
block
49+
.items
50+
.iter()
51+
.for_each(|block| self.convert_block_item(block, instructions));
52+
}
53+
5654
fn convert_block_item(&mut self, block: &ast::BlockItem, instructions: &mut InstructionVec) {
5755
match block {
5856
ast::BlockItem::Declaration(identifier, expr) => {
@@ -86,7 +84,7 @@ impl AstToTacky {
8684
true_stmt,
8785
false_stmt,
8886
} => self.convert_if_stmt(cond, true_stmt, false_stmt.as_ref(), instructions),
89-
ast::Stmt::Compound(block) => todo!(),
87+
ast::Stmt::Compound(block) => self.convert_block(block, instructions),
9088
};
9189
}
9290
fn convert_var(&self, identifier: &Identifier) -> tacky::Value {
@@ -520,4 +518,34 @@ Function main () {
520518
"#;
521519
assert_tacky_has_pretty_print(code, expected);
522520
}
521+
522+
#[test]
523+
fn compound_statement() {
524+
let main = r#"
525+
int main(void) {
526+
int x = 0;
527+
int outer;
528+
{
529+
int y = x + 1;
530+
int x = y + 2;
531+
outer = x -1;
532+
}
533+
return outer;
534+
}
535+
"#;
536+
537+
let expected = r#"
538+
Function main () {
539+
Copy($0, %x.0)
540+
Plus(%x.0,$1,%notcc.tmp.0)
541+
Copy(%notcc.tmp.0, %y.2)
542+
Plus(%y.2,$2,%notcc.tmp.1)
543+
Copy(%notcc.tmp.1, %x.3)
544+
Subtract(%x.3,$1,%notcc.tmp.2)
545+
Copy(%notcc.tmp.2, %outer.1)
546+
Return(%outer.1)
547+
}
548+
"#;
549+
assert_tacky_has_pretty_print(main, expected);
550+
}
523551
}

0 commit comments

Comments
 (0)