mirror of https://github.com/rui314/chibicc
Add "for" statement
This commit is contained in:
parent
72b841508f
commit
f5d480f139
|
@ -73,6 +73,7 @@ typedef enum {
|
|||
ND_ASSIGN, // =
|
||||
ND_RETURN, // "return"
|
||||
ND_IF, // "if"
|
||||
ND_FOR, // "for"
|
||||
ND_BLOCK, // { ... }
|
||||
ND_EXPR_STMT, // Expression statement
|
||||
ND_VAR, // Variable
|
||||
|
@ -87,10 +88,12 @@ struct Node {
|
|||
Node *lhs; // Left-hand side
|
||||
Node *rhs; // Right-hand side
|
||||
|
||||
// "if" statement
|
||||
// "if" or "for" statement
|
||||
Node *cond;
|
||||
Node *then;
|
||||
Node *els;
|
||||
Node *init;
|
||||
Node *inc;
|
||||
|
||||
// Block
|
||||
Node *body;
|
||||
|
|
16
codegen.c
16
codegen.c
|
@ -113,6 +113,22 @@ static void gen_stmt(Node *node) {
|
|||
printf(".L.end.%d:\n", c);
|
||||
return;
|
||||
}
|
||||
case ND_FOR: {
|
||||
int c = count();
|
||||
gen_stmt(node->init);
|
||||
printf(".L.begin.%d:\n", c);
|
||||
if (node->cond) {
|
||||
gen_expr(node->cond);
|
||||
printf(" cmp $0, %%rax\n");
|
||||
printf(" je .L.end.%d\n", c);
|
||||
}
|
||||
gen_stmt(node->then);
|
||||
if (node->inc)
|
||||
gen_expr(node->inc);
|
||||
printf(" jmp .L.begin.%d\n", c);
|
||||
printf(".L.end.%d:\n", c);
|
||||
return;
|
||||
}
|
||||
case ND_BLOCK:
|
||||
for (Node *n = node->body; n; n = n->next)
|
||||
gen_stmt(n);
|
||||
|
|
19
parse.c
19
parse.c
|
@ -64,6 +64,7 @@ static Obj *new_lvar(char *name) {
|
|||
|
||||
// stmt = "return" expr ";"
|
||||
// | "if" "(" expr ")" stmt ("else" stmt)?
|
||||
// | "for" "(" expr-stmt expr? ";" expr? ")" stmt
|
||||
// | "{" compound-stmt
|
||||
// | expr-stmt
|
||||
static Node *stmt(Token **rest, Token *tok) {
|
||||
|
@ -85,6 +86,24 @@ static Node *stmt(Token **rest, Token *tok) {
|
|||
return node;
|
||||
}
|
||||
|
||||
if (equal(tok, "for")) {
|
||||
Node *node = new_node(ND_FOR);
|
||||
tok = skip(tok->next, "(");
|
||||
|
||||
node->init = expr_stmt(&tok, tok);
|
||||
|
||||
if (!equal(tok, ";"))
|
||||
node->cond = expr(&tok, tok);
|
||||
tok = skip(tok, ";");
|
||||
|
||||
if (!equal(tok, ")"))
|
||||
node->inc = expr(&tok, tok);
|
||||
tok = skip(tok, ")");
|
||||
|
||||
node->then = stmt(rest, tok);
|
||||
return node;
|
||||
}
|
||||
|
||||
if (equal(tok, "{"))
|
||||
return compound_stmt(rest, tok->next);
|
||||
|
||||
|
|
3
test.sh
3
test.sh
|
@ -69,4 +69,7 @@ assert 2 '{ if (2-1) return 2; return 3; }'
|
|||
assert 4 '{ if (0) { 1; 2; return 3; } else { return 4; } }'
|
||||
assert 3 '{ if (1) { 1; 2; return 3; } else { return 4; } }'
|
||||
|
||||
assert 55 '{ i=0; j=0; for (i=0; i<=10; i=i+1) j=i+j; return j; }'
|
||||
assert 3 '{ for (;;) {return 3;} return 5; }'
|
||||
|
||||
echo OK
|
||||
|
|
|
@ -80,7 +80,7 @@ static int read_punct(char *p) {
|
|||
}
|
||||
|
||||
static bool is_keyword(Token *tok) {
|
||||
static char *kw[] = {"return", "if", "else"};
|
||||
static char *kw[] = {"return", "if", "else", "for"};
|
||||
|
||||
for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++)
|
||||
if (equal(tok, kw[i]))
|
||||
|
|
Loading…
Reference in New Issue