Skip to content

Commit

Permalink
break
Browse files Browse the repository at this point in the history
  • Loading branch information
diohabara committed Jul 19, 2023
1 parent 9cd1681 commit eb3eefb
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 6 deletions.
1 change: 1 addition & 0 deletions ccc.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ typedef enum {
ND_WHILE, // "while"
ND_FOR, // "for"
ND_BLOCK, // { ... }
ND_BREAK, // "break"
ND_FUNCALL, // Function call
ND_EXPR_STMT, // Expression statement
ND_STMT_EXPR, // statement expression
Expand Down
27 changes: 22 additions & 5 deletions codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ char *argreg2[] = {"di", "si", "dx", "cx", "r8w", "r9w"};
char *argreg4[] = {"edi", "esi", "edx", "ecx", "r8d", "r9d"};
char *argreg8[] = {"rdi", "rsi", "rdx", "rcx", "r8", "r9"};

int labelseq = 0;
int labelseq;
int brkseq;
char *funcname;

void truncate(Type *ty) {
Expand Down Expand Up @@ -216,36 +217,52 @@ void gen(Node *node) {
}
case ND_WHILE: {
int seq = labelseq++;
int brk = brkseq;
brkseq = seq;

printf(".Lbegin%d:\n", seq);
gen(node->cond);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" je .Lend%d\n", seq);
printf(" je .L.break.%d\n", seq);
gen(node->then);
printf(" jmp .Lbegin%d\n", seq);
printf(".Lend%d:\n", seq);
printf(".L.break.%d:\n", seq);

brkseq = brk;
return;
}
case ND_FOR: {
int seq = labelseq++;
int brk = brkseq;
brkseq = seq;

if (node->init) gen(node->init);
printf(".Lbegin%d:\n", seq);
if (node->cond) {
gen(node->cond);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" je .Lend%d\n", seq);
printf(" je .L.break.%d\n", seq);
}
gen(node->then);
if (node->inc) gen(node->inc);
printf(" jmp .Lbegin%d\n", seq);
printf(".Lend%d:\n", seq);
printf(".L.break.%d:\n", seq);

brkseq = brk;
return;
}
case ND_BLOCK:
case ND_STMT_EXPR:
for (Node *n = node->body; n; n = n->next) gen(n);
return;
case ND_BREAK:
if (brkseq == 0) {
error_tok(node->tok, "stray break");
}
printf(" jmp .L.break.%d\n", brkseq);
return;
case ND_FUNCALL: {
int nargs = 0;
for (Node *arg = node->args; arg; arg = arg->next) {
Expand Down
5 changes: 5 additions & 0 deletions parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@ bool is_typename() {
// | "while" "(" expr ")" stmt
// | "for" "(" (expr? ";" | declaration) expr? ";" expr? ")" stmt
// | "{" stmt* "}"
// | "break" ";"
// | declaration
// | expr ";"
Node *stmt() {
Expand Down Expand Up @@ -709,6 +710,10 @@ Node *stmt() {
node->body = head.next;
return node;
}
if (tok = consume("break")) {
expect(";");
return new_node(ND_BREAK, tok);
}
if (is_typename()) {
return declaration();
}
Expand Down
5 changes: 5 additions & 0 deletions tests
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,11 @@ int main() {

assert(3, ({ int x[2]; x[0]=3; param_decay(x); }), "int x[2]; x[0]=3; param_decay(x);");

assert(3, ({ int i=0; for(;i<10;i++) { if (i == 3) break; } i; }), "int i=0; for(;i<10;i++) { if (i == 3) break; } i;");
assert(4, ({ int i=0; while (1) { if (i++ == 3) break; } i; }), "int i=0; while { if (i == 3) break; } i;");
assert(3, ({ int i=0; for(;i<10;i++) { for (;;) break; if (i == 3) break; } i; }), "int i=0; for(;i<10;i++) { if (i == 3) break; } i;");
assert(4, ({ int i=0; while (1) { while(1) break; if (i++ == 3) break; } i; }), "int i=0; while { if (i == 3) break; } i;");

printf("OK\n");
return 0;
}
2 changes: 1 addition & 1 deletion tokenize.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ char *starts_with_reserved(char *p) {
// Keyword
static char *kw[] = {"return", "if", "else", "while", "for", "char",
"int", "sizeof", "struct", "typedef", "short", "long",
"void", "_Bool", "enum", "static"};
"void", "_Bool", "enum", "static", "break"};
for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++) {
int len = strlen(kw[i]);
if (startswith(p, kw[i]) && !is_alnum(p[len])) {
Expand Down

0 comments on commit eb3eefb

Please sign in to comment.