mirror of https://github.com/rui314/chibicc
Add continue statement
This commit is contained in:
parent
b3047f2317
commit
3c83dfd8af
|
@ -144,8 +144,9 @@ struct Node {
|
|||
Node *init;
|
||||
Node *inc;
|
||||
|
||||
// "break" label
|
||||
// "break" and "continue" labels
|
||||
char *brk_label;
|
||||
char *cont_label;
|
||||
|
||||
// Block or statement expression
|
||||
Node *body;
|
||||
|
|
|
@ -362,6 +362,7 @@ static void gen_stmt(Node *node) {
|
|||
println(" je %s", node->brk_label);
|
||||
}
|
||||
gen_stmt(node->then);
|
||||
println("%s:", node->cont_label);
|
||||
if (node->inc)
|
||||
gen_expr(node->inc);
|
||||
println(" jmp .L.begin.%d", c);
|
||||
|
|
21
parse.c
21
parse.c
|
@ -71,8 +71,9 @@ static Obj *current_fn;
|
|||
static Node *gotos;
|
||||
static Node *labels;
|
||||
|
||||
// Current "goto" jump target.
|
||||
// Current "goto" and "continue" jump targets.
|
||||
static char *brk_label;
|
||||
static char *cont_label;
|
||||
|
||||
static bool is_typename(Token *tok);
|
||||
static Type *declspec(Token **rest, Token *tok, VarAttr *attr);
|
||||
|
@ -586,6 +587,7 @@ static bool is_typename(Token *tok) {
|
|||
// | "while" "(" expr ")" stmt
|
||||
// | "goto" ident ";"
|
||||
// | "break" ";"
|
||||
// | "continue" ";"
|
||||
// | ident ":" stmt
|
||||
// | "{" compound-stmt
|
||||
// | expr-stmt
|
||||
|
@ -619,7 +621,9 @@ static Node *stmt(Token **rest, Token *tok) {
|
|||
enter_scope();
|
||||
|
||||
char *brk = brk_label;
|
||||
char *cont = cont_label;
|
||||
brk_label = node->brk_label = new_unique_name();
|
||||
cont_label = node->cont_label = new_unique_name();
|
||||
|
||||
if (is_typename(tok)) {
|
||||
Type *basety = declspec(&tok, tok, NULL);
|
||||
|
@ -640,6 +644,7 @@ static Node *stmt(Token **rest, Token *tok) {
|
|||
|
||||
leave_scope();
|
||||
brk_label = brk;
|
||||
cont_label = cont;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -650,9 +655,14 @@ static Node *stmt(Token **rest, Token *tok) {
|
|||
tok = skip(tok, ")");
|
||||
|
||||
char *brk = brk_label;
|
||||
char *cont = cont_label;
|
||||
brk_label = node->brk_label = new_unique_name();
|
||||
cont_label = node->cont_label = new_unique_name();
|
||||
|
||||
node->then = stmt(rest, tok);
|
||||
|
||||
brk_label = brk;
|
||||
cont_label = cont;
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -674,6 +684,15 @@ static Node *stmt(Token **rest, Token *tok) {
|
|||
return node;
|
||||
}
|
||||
|
||||
if (equal(tok, "continue")) {
|
||||
if (!cont_label)
|
||||
error_tok(tok, "stray continue");
|
||||
Node *node = new_node(ND_GOTO, tok);
|
||||
node->unique_label = cont_label;
|
||||
*rest = skip(tok->next, ";");
|
||||
return node;
|
||||
}
|
||||
|
||||
if (tok->kind == TK_IDENT && equal(tok->next, ":")) {
|
||||
Node *node = new_node(ND_LABEL, tok);
|
||||
node->label = strndup(tok->loc, tok->len);
|
||||
|
|
|
@ -47,6 +47,13 @@ int main() {
|
|||
ASSERT(3, ({ int i=0; for(;i<10;i++) { for (;;) break; if (i == 3) break; } i; }));
|
||||
ASSERT(4, ({ int i=0; while (1) { while(1) break; if (i++ == 3) break; } i; }));
|
||||
|
||||
ASSERT(10, ({ int i=0; int j=0; for (;i<10;i++) { if (i>5) continue; j++; } i; }));
|
||||
ASSERT(6, ({ int i=0; int j=0; for (;i<10;i++) { if (i>5) continue; j++; } j; }));
|
||||
ASSERT(10, ({ int i=0; int j=0; for(;!i;) { for (;j!=10;j++) continue; break; } j; }));
|
||||
ASSERT(11, ({ int i=0; int j=0; while (i++<10) { if (i>5) continue; j++; } i; }));
|
||||
ASSERT(5, ({ int i=0; int j=0; while (i++<10) { if (i>5) continue; j++; } j; }));
|
||||
ASSERT(11, ({ int i=0; int j=0; while(!i) { while (j++!=10) continue; break; } j; }));
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -131,7 +131,7 @@ static bool is_keyword(Token *tok) {
|
|||
static char *kw[] = {
|
||||
"return", "if", "else", "for", "while", "int", "sizeof", "char",
|
||||
"struct", "union", "short", "long", "void", "typedef", "_Bool",
|
||||
"enum", "static", "goto", "break",
|
||||
"enum", "static", "goto", "break", "continue",
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++)
|
||||
|
|
Loading…
Reference in New Issue