Add compound literals

This commit is contained in:
Rui Ueyama 2019-08-24 07:45:14 +09:00
parent 94ed9371e0
commit dbb29fe796
2 changed files with 56 additions and 1 deletions

24
parse.c
View File

@ -1723,12 +1723,34 @@ static Node *mul(Token **rest, Token *tok) {
}
}
// cast = "(" type-name ")" cast | unary
// compound-literal = initializer "}"
static Node *compound_literal(Token **rest, Token *tok, Type *ty, Token *start) {
if (scope_depth == 0) {
Var *var = new_anon_gvar(ty);
gvar_initializer(rest, tok, var);
return new_var_node(var, start);
}
Var *var = new_lvar(new_unique_name(), ty);
Node *lhs = lvar_initializer(rest, tok, var);
Node *rhs = new_var_node(var, tok);
return new_binary(ND_COMMA, lhs, rhs, tok);
}
// cast = "(" type-name ")" "{" compound-literal
// | "(" type-name ")" cast
// | unary
static Node *cast(Token **rest, Token *tok) {
if (equal(tok, "(") && is_typename(tok->next)) {
Token *start = tok;
Type *ty = typename(&tok, tok->next);
tok = skip(tok, ")");
// compound literal
if (equal(tok, "{"))
return compound_literal(rest, tok, ty, start);
// type cast
Node *node = new_cast(cast(rest, tok), ty);
node->tok = start;
return node;

33
test/complit.c Normal file
View File

@ -0,0 +1,33 @@
#include "test.h"
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
};
int main() {
ASSERT(1, (int){1});
ASSERT(2, ((int[]){0,1,2})[2]);
ASSERT('a', ((struct {char a; int b;}){'a', 3}).a);
ASSERT(3, ({ int x=3; (int){x}; }));
(int){3} = 5;
ASSERT(1, tree->val);
ASSERT(2, tree->lhs->val);
ASSERT(3, tree->lhs->lhs->val);
ASSERT(4, tree->lhs->rhs->val);
printf("OK\n");
return 0;
}