Add string literal initializer

This commit is contained in:
Rui Ueyama 2019-08-18 16:34:39 +09:00
parent a754732c04
commit 0d717373cc
3 changed files with 43 additions and 13 deletions

View File

@ -10,6 +10,9 @@
#include <string.h>
#include <strings.h>
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) < (y) ? (x) : (y))
typedef struct Type Type;
typedef struct Node Node;
typedef struct Member Member;

45
parse.c
View File

@ -111,6 +111,8 @@ static Type *enum_specifier(Token **rest, Token *tok);
static Type *type_suffix(Token **rest, Token *tok, Type *ty);
static Type *declarator(Token **rest, Token *tok, Type *ty);
static Node *declaration(Token **rest, Token *tok, Type *basety);
static void initializer2(Token **rest, Token *tok, Initializer *init);
static Initializer *initializer(Token **rest, Token *tok, Type *ty);
static Node *lvar_initializer(Token **rest, Token *tok, Obj *var);
static Node *compound_stmt(Token **rest, Token *tok);
static Node *stmt(Token **rest, Token *tok);
@ -613,21 +615,38 @@ static Token *skip_excess_element(Token *tok) {
return tok;
}
// initializer = "{" initializer ("," initializer)* "}"
// | assign
// string-initializer = string-literal
static void string_initializer(Token **rest, Token *tok, Initializer *init) {
int len = MIN(init->ty->array_len, tok->ty->array_len);
for (int i = 0; i < len; i++)
init->children[i]->expr = new_num(tok->str[i], tok);
*rest = tok->next;
}
// array-initializer = "{" initializer ("," initializer)* "}"
static void array_initializer(Token **rest, Token *tok, Initializer *init) {
tok = skip(tok, "{");
for (int i = 0; !consume(rest, tok, "}"); i++) {
if (i > 0)
tok = skip(tok, ",");
if (i < init->ty->array_len)
initializer2(&tok, tok, init->children[i]);
else
tok = skip_excess_element(tok);
}
}
// initializer = string-initializer | array-initializer | assign
static void initializer2(Token **rest, Token *tok, Initializer *init) {
if (init->ty->kind == TY_ARRAY && tok->kind == TK_STR) {
string_initializer(rest, tok, init);
return;
}
if (init->ty->kind == TY_ARRAY) {
tok = skip(tok, "{");
for (int i = 0; !consume(rest, tok, "}"); i++) {
if (i > 0)
tok = skip(tok, ",");
if (i < init->ty->array_len)
initializer2(&tok, tok, init->children[i]);
else
tok = skip_excess_element(tok);
}
array_initializer(rest, tok, init);
return;
}

View File

@ -18,6 +18,14 @@ int main() {
ASSERT(0, ({ int x[2][3]={{1,2}}; x[1][0]; }));
ASSERT(0, ({ int x[2][3]={{1,2}}; x[1][2]; }));
ASSERT('a', ({ char x[4]="abc"; x[0]; }));
ASSERT('c', ({ char x[4]="abc"; x[2]; }));
ASSERT(0, ({ char x[4]="abc"; x[3]; }));
ASSERT('a', ({ char x[2][4]={"abc","def"}; x[0][0]; }));
ASSERT(0, ({ char x[2][4]={"abc","def"}; x[0][3]; }));
ASSERT('d', ({ char x[2][4]={"abc","def"}; x[1][0]; }));
ASSERT('f', ({ char x[2][4]={"abc","def"}; x[1][2]; }));
printf("OK\n");
return 0;
}