mirror of https://github.com/rui314/chibicc
Add compound literals
This commit is contained in:
parent
a4a0a84848
commit
a554dff9d1
|
@ -16,6 +16,9 @@ static void gen(Node *node);
|
|||
static void gen_addr(Node *node) {
|
||||
switch (node->kind) {
|
||||
case ND_VAR: {
|
||||
if (node->init)
|
||||
gen(node->init);
|
||||
|
||||
Var *var = node->var;
|
||||
if (var->is_local) {
|
||||
printf(" lea rax, [rbp-%d]\n", var->offset);
|
||||
|
@ -216,6 +219,12 @@ static void gen(Node *node) {
|
|||
printf(" add rsp, 8\n");
|
||||
return;
|
||||
case ND_VAR:
|
||||
if (node->init)
|
||||
gen(node->init);
|
||||
gen_addr(node);
|
||||
if (node->ty->kind != TY_ARRAY)
|
||||
load(node->ty);
|
||||
return;
|
||||
case ND_MEMBER:
|
||||
gen_addr(node);
|
||||
if (node->ty->kind != TY_ARRAY)
|
||||
|
|
49
parse.c
49
parse.c
|
@ -205,6 +205,7 @@ static Node *mul(void);
|
|||
static Node *cast(void);
|
||||
static Node *unary(void);
|
||||
static Node *postfix(void);
|
||||
static Node *compound_literal(void);
|
||||
static Node *primary(void);
|
||||
|
||||
// Determine whether the next top-level item is a function
|
||||
|
@ -1580,10 +1581,12 @@ static Node *cast(void) {
|
|||
if (is_typename()) {
|
||||
Type *ty = type_name();
|
||||
expect(")");
|
||||
Node *node = new_unary(ND_CAST, cast(), tok);
|
||||
add_type(node->lhs);
|
||||
node->ty = ty;
|
||||
return node;
|
||||
if (!consume("{")) {
|
||||
Node *node = new_unary(ND_CAST, cast(), tok);
|
||||
add_type(node->lhs);
|
||||
node->ty = ty;
|
||||
return node;
|
||||
}
|
||||
}
|
||||
token = tok;
|
||||
}
|
||||
|
@ -1637,11 +1640,17 @@ static Node *struct_ref(Node *lhs) {
|
|||
return node;
|
||||
}
|
||||
|
||||
// postfix = primary ("[" expr "]" | "." ident | "->" ident | "++" | "--")*
|
||||
// postfix = compound-literal
|
||||
// | primary ("[" expr "]" | "." ident | "->" ident | "++" | "--")*
|
||||
static Node *postfix(void) {
|
||||
Node *node = primary();
|
||||
Token *tok;
|
||||
|
||||
Node *node = compound_literal();
|
||||
if (node)
|
||||
return node;
|
||||
|
||||
node = primary();
|
||||
|
||||
for (;;) {
|
||||
if (tok = consume("[")) {
|
||||
// x[y] is short for *(x+y)
|
||||
|
@ -1677,6 +1686,34 @@ static Node *postfix(void) {
|
|||
}
|
||||
}
|
||||
|
||||
// compound-literal = "(" type-name ")" "{" (gvar-initializer | lvar-initializer) "}"
|
||||
static Node *compound_literal(void) {
|
||||
Token *tok = token;
|
||||
if (!consume("(") || !is_typename()) {
|
||||
token = tok;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Type *ty = type_name();
|
||||
expect(")");
|
||||
|
||||
if (!peek("{")) {
|
||||
token = tok;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (scope_depth == 0) {
|
||||
Var *var = new_gvar(new_label(), ty, true);
|
||||
var->initializer = gvar_initializer(ty);
|
||||
return new_var_node(var, tok);
|
||||
}
|
||||
|
||||
Var *var = new_lvar(new_label(), ty);
|
||||
Node *node = new_var_node(var, tok);
|
||||
node->init = lvar_initializer(var, tok);
|
||||
return node;
|
||||
}
|
||||
|
||||
// stmt-expr = "(" "{" stmt stmt* "}" ")"
|
||||
//
|
||||
// Statement expression is a GNU C extension.
|
||||
|
|
26
tests
26
tests
|
@ -42,6 +42,22 @@ int *g25=&g24;
|
|||
int g26[3] = {1, 2, 3};
|
||||
int *g27 = g26 + 1;
|
||||
|
||||
typedef struct Tree {
|
||||
int val;
|
||||
struct Tree *lhs;
|
||||
struct Tree *rhs;
|
||||
} Tree;
|
||||
|
||||
Tree *tree = &(Tree){
|
||||
1,
|
||||
&(Tree){
|
||||
2,
|
||||
&(Tree){ 3, 0, 0 },
|
||||
&(Tree){ 4, 0, 0 },
|
||||
},
|
||||
0,
|
||||
};
|
||||
|
||||
extern int ext1;
|
||||
extern int *ext2;
|
||||
|
||||
|
@ -652,6 +668,16 @@ int main() {
|
|||
assert(4, counter(), "counter()");
|
||||
assert(6, counter(), "counter()");
|
||||
|
||||
assert(1, (int){1}, "(int){1}");
|
||||
assert(2, ((int[]){0,1,2})[2], "(int[]){0,1,2}[2]");
|
||||
assert('a', ((struct {char a; int b;}){'a', 3}).a, "((struct {char a; int b;}){'a', 3}).a");
|
||||
assert(3, ({ int x=3; (int){x}; }), "int x=3; (int){x};");
|
||||
|
||||
assert(1, tree->val, "tree->val");
|
||||
assert(2, tree->lhs->val, "tree->lhs->val");
|
||||
assert(3, tree->lhs->lhs->val, "tree->lhs->lhs->val");
|
||||
assert(4, tree->lhs->rhs->val, "tree->lhs->rhs->val");
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue