Fix variable declaration.

This commit is contained in:
Rui Ueyama 2018-08-25 01:33:43 +00:00
parent 55ab29aa57
commit 5eb746ea74
3 changed files with 47 additions and 48 deletions

90
parse.c
View File

@ -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;
}

View File

@ -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];
}

View File

@ -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];