mirror of https://github.com/rui314/chibicc
Add { ... }
This commit is contained in:
parent
6cc1c1f064
commit
18ac283a5d
|
@ -72,6 +72,7 @@ typedef enum {
|
|||
ND_LE, // <=
|
||||
ND_ASSIGN, // =
|
||||
ND_RETURN, // "return"
|
||||
ND_BLOCK, // { ... }
|
||||
ND_EXPR_STMT, // Expression statement
|
||||
ND_VAR, // Variable
|
||||
ND_NUM, // Integer
|
||||
|
@ -83,6 +84,10 @@ struct Node {
|
|||
Node *next; // Next node
|
||||
Node *lhs; // Left-hand side
|
||||
Node *rhs; // Right-hand side
|
||||
|
||||
// Block
|
||||
Node *body;
|
||||
|
||||
Obj *var; // Used if kind == ND_VAR
|
||||
int val; // Used if kind == ND_NUM
|
||||
};
|
||||
|
|
10
codegen.c
10
codegen.c
|
@ -95,6 +95,10 @@ static void gen_expr(Node *node) {
|
|||
|
||||
static void gen_stmt(Node *node) {
|
||||
switch (node->kind) {
|
||||
case ND_BLOCK:
|
||||
for (Node *n = node->body; n; n = n->next)
|
||||
gen_stmt(n);
|
||||
return;
|
||||
case ND_RETURN:
|
||||
gen_expr(node->lhs);
|
||||
printf(" jmp .L.return\n");
|
||||
|
@ -128,10 +132,8 @@ void codegen(Function *prog) {
|
|||
printf(" mov %%rsp, %%rbp\n");
|
||||
printf(" sub $%d, %%rsp\n", prog->stack_size);
|
||||
|
||||
for (Node *n = prog->body; n; n = n->next) {
|
||||
gen_stmt(n);
|
||||
assert(depth == 0);
|
||||
}
|
||||
gen_stmt(prog->body);
|
||||
assert(depth == 0);
|
||||
|
||||
printf(".L.return:\n");
|
||||
printf(" mov %%rbp, %%rsp\n");
|
||||
|
|
26
parse.c
26
parse.c
|
@ -4,6 +4,7 @@
|
|||
// accumulated to this list.
|
||||
Obj *locals;
|
||||
|
||||
static Node *compound_stmt(Token **rest, Token *tok);
|
||||
static Node *expr(Token **rest, Token *tok);
|
||||
static Node *expr_stmt(Token **rest, Token *tok);
|
||||
static Node *assign(Token **rest, Token *tok);
|
||||
|
@ -62,6 +63,7 @@ static Obj *new_lvar(char *name) {
|
|||
}
|
||||
|
||||
// stmt = "return" expr ";"
|
||||
// | "{" compound-stmt
|
||||
// | expr-stmt
|
||||
static Node *stmt(Token **rest, Token *tok) {
|
||||
if (equal(tok, "return")) {
|
||||
|
@ -70,9 +72,25 @@ static Node *stmt(Token **rest, Token *tok) {
|
|||
return node;
|
||||
}
|
||||
|
||||
if (equal(tok, "{"))
|
||||
return compound_stmt(rest, tok->next);
|
||||
|
||||
return expr_stmt(rest, tok);
|
||||
}
|
||||
|
||||
// compound-stmt = stmt* "}"
|
||||
static Node *compound_stmt(Token **rest, Token *tok) {
|
||||
Node head = {};
|
||||
Node *cur = &head;
|
||||
while (!equal(tok, "}"))
|
||||
cur = cur->next = stmt(&tok, tok);
|
||||
|
||||
Node *node = new_node(ND_BLOCK);
|
||||
node->body = head.next;
|
||||
*rest = tok->next;
|
||||
return node;
|
||||
}
|
||||
|
||||
// expr-stmt = expr ";"
|
||||
static Node *expr_stmt(Token **rest, Token *tok) {
|
||||
Node *node = new_unary(ND_EXPR_STMT, expr(&tok, tok));
|
||||
|
@ -223,14 +241,10 @@ static Node *primary(Token **rest, Token *tok) {
|
|||
|
||||
// program = stmt*
|
||||
Function *parse(Token *tok) {
|
||||
Node head = {};
|
||||
Node *cur = &head;
|
||||
|
||||
while (tok->kind != TK_EOF)
|
||||
cur = cur->next = stmt(&tok, tok);
|
||||
tok = skip(tok, "{");
|
||||
|
||||
Function *prog = calloc(1, sizeof(Function));
|
||||
prog->body = head.next;
|
||||
prog->body = compound_stmt(&tok, tok);
|
||||
prog->locals = locals;
|
||||
return prog;
|
||||
}
|
||||
|
|
74
test.sh
74
test.sh
|
@ -16,47 +16,49 @@ assert() {
|
|||
fi
|
||||
}
|
||||
|
||||
assert 0 'return 0;'
|
||||
assert 42 'return 42;'
|
||||
assert 21 'return 5+20-4;'
|
||||
assert 41 'return 12 + 34 - 5 ;'
|
||||
assert 47 'return 5+6*7;'
|
||||
assert 15 'return 5*(9-6);'
|
||||
assert 4 'return (3+5)/2;'
|
||||
assert 10 'return -10+20;'
|
||||
assert 10 'return - -10;'
|
||||
assert 10 'return - - +10;'
|
||||
assert 0 '{ return 0; }'
|
||||
assert 42 '{ return 42; }'
|
||||
assert 21 '{ return 5+20-4; }'
|
||||
assert 41 '{ return 12 + 34 - 5 ; }'
|
||||
assert 47 '{ return 5+6*7; }'
|
||||
assert 15 '{ return 5*(9-6); }'
|
||||
assert 4 '{ return (3+5)/2; }'
|
||||
assert 10 '{ return -10+20; }'
|
||||
assert 10 '{ return - -10; }'
|
||||
assert 10 '{ return - - +10; }'
|
||||
|
||||
assert 0 'return 0==1;'
|
||||
assert 1 'return 42==42;'
|
||||
assert 1 'return 0!=1;'
|
||||
assert 0 'return 42!=42;'
|
||||
assert 0 '{ return 0==1; }'
|
||||
assert 1 '{ return 42==42; }'
|
||||
assert 1 '{ return 0!=1; }'
|
||||
assert 0 '{ return 42!=42; }'
|
||||
|
||||
assert 1 'return 0<1;'
|
||||
assert 0 'return 1<1;'
|
||||
assert 0 'return 2<1;'
|
||||
assert 1 'return 0<=1;'
|
||||
assert 1 'return 1<=1;'
|
||||
assert 0 'return 2<=1;'
|
||||
assert 1 '{ return 0<1; }'
|
||||
assert 0 '{ return 1<1; }'
|
||||
assert 0 '{ return 2<1; }'
|
||||
assert 1 '{ return 0<=1; }'
|
||||
assert 1 '{ return 1<=1; }'
|
||||
assert 0 '{ return 2<=1; }'
|
||||
|
||||
assert 1 'return 1>0;'
|
||||
assert 0 'return 1>1;'
|
||||
assert 0 'return 1>2;'
|
||||
assert 1 'return 1>=0;'
|
||||
assert 1 'return 1>=1;'
|
||||
assert 0 'return 1>=2;'
|
||||
assert 1 '{ return 1>0; }'
|
||||
assert 0 '{ return 1>1; }'
|
||||
assert 0 '{ return 1>2; }'
|
||||
assert 1 '{ return 1>=0; }'
|
||||
assert 1 '{ return 1>=1; }'
|
||||
assert 0 '{ return 1>=2; }'
|
||||
|
||||
assert 3 'a=3; return a;'
|
||||
assert 8 'a=3; z=5; return a+z;'
|
||||
assert 3 '{ a=3; return a; }'
|
||||
assert 8 '{ a=3; z=5; return a+z; }'
|
||||
|
||||
assert 3 'a=3; return a;'
|
||||
assert 8 'a=3; z=5; return a+z;'
|
||||
assert 6 'a=b=3; return a+b;'
|
||||
assert 3 'foo=3; return foo;'
|
||||
assert 8 'foo123=3; bar=5; return foo123+bar;'
|
||||
assert 3 '{ a=3; return a; }'
|
||||
assert 8 '{ a=3; z=5; return a+z; }'
|
||||
assert 6 '{ a=b=3; return a+b; }'
|
||||
assert 3 '{ foo=3; return foo; }'
|
||||
assert 8 '{ foo123=3; bar=5; return foo123+bar; }'
|
||||
|
||||
assert 1 'return 1; 2; 3;'
|
||||
assert 2 '1; return 2; 3;'
|
||||
assert 3 '1; 2; return 3;'
|
||||
assert 1 '{ return 1; 2; 3; }'
|
||||
assert 2 '{ 1; return 2; 3; }'
|
||||
assert 3 '{ 1; 2; return 3; }'
|
||||
|
||||
assert 3 '{ {1; {2;} return 3;} }'
|
||||
|
||||
echo OK
|
||||
|
|
Loading…
Reference in New Issue