mirror of https://github.com/rui314/9cc.git
Fix variable declaration.
This commit is contained in:
parent
55ab29aa57
commit
5eb746ea74
90
parse.c
90
parse.c
|
@ -90,7 +90,7 @@ static bool is_typename() {
|
|||
t->ty == TK_STRUCT;
|
||||
}
|
||||
|
||||
static Node *decl();
|
||||
static Node *declaration();
|
||||
|
||||
static void add_members(Type *ty, Vector *members) {
|
||||
int off = 0;
|
||||
|
@ -111,7 +111,7 @@ static void add_members(Type *ty, Vector *members) {
|
|||
ty->size = roundup(off, ty->align);
|
||||
}
|
||||
|
||||
static Type *read_type() {
|
||||
static Type *decl_specifiers() {
|
||||
Token *t = tokens->data[pos++];
|
||||
|
||||
if (t->ty == TK_IDENT) {
|
||||
|
@ -142,7 +142,7 @@ static Type *read_type() {
|
|||
if (consume('{')) {
|
||||
members = new_vec();
|
||||
while (!consume('}'))
|
||||
vec_push(members, decl());
|
||||
vec_push(members, declaration());
|
||||
}
|
||||
|
||||
if (!tag && !members)
|
||||
|
@ -165,8 +165,7 @@ static Type *read_type() {
|
|||
return ty;
|
||||
}
|
||||
|
||||
pos--;
|
||||
return NULL;
|
||||
bad_token(t, "typename expected");
|
||||
}
|
||||
|
||||
static Node *new_binop(int op, Node *lhs, Node *rhs) {
|
||||
|
@ -470,17 +469,6 @@ static Node *expr() {
|
|||
return new_binop(',', lhs, expr());
|
||||
}
|
||||
|
||||
static Type *type() {
|
||||
Token *t = tokens->data[pos];
|
||||
Type *ty = read_type();
|
||||
if (!ty)
|
||||
bad_token(t, "typename expected");
|
||||
|
||||
while (consume('*'))
|
||||
ty = ptr_to(ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
static Type *read_array(Type *ty) {
|
||||
Vector *v = new_vec();
|
||||
while (consume('[')) {
|
||||
|
@ -498,35 +486,50 @@ static Type *read_array(Type *ty) {
|
|||
return ty;
|
||||
}
|
||||
|
||||
static Node *decl() {
|
||||
Node *node = calloc(1, sizeof(Node));
|
||||
node->op = ND_VARDEF;
|
||||
static Node *declarator(Type *ty);
|
||||
|
||||
// Read the first half of type name (e.g. `int *`).
|
||||
node->ty = type();
|
||||
static Node *direct_decl(Type *ty) {
|
||||
Token *t = tokens->data[pos];
|
||||
Node *node;
|
||||
Type *placeholder = calloc(1, sizeof(Type));
|
||||
|
||||
// Read an identifier.
|
||||
node->name = ident();
|
||||
if (t->ty == TK_IDENT) {
|
||||
node = calloc(1, sizeof(Node));
|
||||
node->op = ND_VARDEF;
|
||||
node->ty = placeholder;
|
||||
node->name = ident();
|
||||
} else if (consume('(')) {
|
||||
node = declarator(placeholder);
|
||||
expect(')');
|
||||
} else {
|
||||
bad_token(t, "bad direct-declarator");
|
||||
}
|
||||
|
||||
// Read the second half of type name (e.g. `[3][5]`).
|
||||
Token *t = tokens->data[pos];
|
||||
node->ty = read_array(node->ty);
|
||||
if (node->ty->ty == VOID)
|
||||
bad_token(t, "void variable");
|
||||
*placeholder = *read_array(ty);
|
||||
|
||||
// Read an initializer.
|
||||
if (consume('='))
|
||||
node->init = assign();
|
||||
return node;
|
||||
}
|
||||
|
||||
static Node *declarator(Type *ty) {
|
||||
while (consume('*'))
|
||||
ty = ptr_to(ty);
|
||||
return direct_decl(ty);
|
||||
}
|
||||
|
||||
static Node *declaration() {
|
||||
Type *ty = decl_specifiers();
|
||||
Node *node = declarator(ty);
|
||||
expect(';');
|
||||
return node;
|
||||
}
|
||||
|
||||
static Node *param() {
|
||||
Node *node = calloc(1, sizeof(Node));
|
||||
node->op = ND_VARDEF;
|
||||
node->ty = type();
|
||||
node->name = ident();
|
||||
return node;
|
||||
static Node *param_declaration() {
|
||||
Type *ty = decl_specifiers();
|
||||
return declarator(ty);
|
||||
}
|
||||
|
||||
static Node *expr_stmt() {
|
||||
|
@ -541,7 +544,7 @@ static Node *stmt() {
|
|||
|
||||
switch (t->ty) {
|
||||
case TK_TYPEDEF: {
|
||||
Node *node = decl();
|
||||
Node *node = declaration();
|
||||
assert(node->name);
|
||||
map_put(env->typedefs, node->name, node->ty);
|
||||
return &null_stmt;
|
||||
|
@ -562,7 +565,7 @@ static Node *stmt() {
|
|||
expect('(');
|
||||
|
||||
if (is_typename())
|
||||
node->init = decl();
|
||||
node->init = declaration();
|
||||
else if (consume(';'))
|
||||
node->init = &null_stmt;
|
||||
else
|
||||
|
@ -616,7 +619,7 @@ static Node *stmt() {
|
|||
default:
|
||||
pos--;
|
||||
if (is_typename())
|
||||
return decl();
|
||||
return declaration();
|
||||
return expr_stmt();
|
||||
}
|
||||
}
|
||||
|
@ -637,11 +640,9 @@ static Node *toplevel() {
|
|||
bool is_typedef = consume(TK_TYPEDEF);
|
||||
bool is_extern = consume(TK_EXTERN);
|
||||
|
||||
Token *t = tokens->data[pos];
|
||||
|
||||
Type *ty = type();
|
||||
if (!ty)
|
||||
bad_token(t, "typename expected");
|
||||
Type *ty = decl_specifiers();
|
||||
while (consume('*'))
|
||||
ty = ptr_to(ty);
|
||||
|
||||
char *name = ident();
|
||||
|
||||
|
@ -654,15 +655,16 @@ static Node *toplevel() {
|
|||
node->args = new_vec();
|
||||
|
||||
if (!consume(')')) {
|
||||
vec_push(node->args, param());
|
||||
vec_push(node->args, param_declaration());
|
||||
while (consume(','))
|
||||
vec_push(node->args, param());
|
||||
vec_push(node->args, param_declaration());
|
||||
expect(')');
|
||||
}
|
||||
|
||||
Token *t = tokens->data[pos];
|
||||
expect('{');
|
||||
if (is_typedef)
|
||||
bad_token(t, "typedef %s has function definition");
|
||||
bad_token(t, "typedef has function definition");
|
||||
node->body = compound_stmt();
|
||||
return node;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
// This file is compiled by gcc.
|
||||
|
||||
int global_arr[1] = {5};
|
||||
|
||||
int add2(int a[][2]) {
|
||||
return a[0][0] + a[1][0];
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ int two() { return 2; }
|
|||
int plus(int x, int y) { return x + y; }
|
||||
int mul(int x, int y) { return x * y; }
|
||||
int add(int a, int b, int c, int d, int e, int f) { return a+b+c+d+e+f; }
|
||||
int add2(int (*a)[2]) { return a[0][0] + a[1][0]; }
|
||||
|
||||
int var1;
|
||||
int var2[5];
|
||||
|
|
Loading…
Reference in New Issue