mirror of https://github.com/rui314/chibicc
Add ?: operator
This commit is contained in:
parent
1bb4c6d4b8
commit
0924ab0aa5
|
@ -100,6 +100,7 @@ typedef enum {
|
|||
ND_LT, // <
|
||||
ND_LE, // <=
|
||||
ND_ASSIGN, // =
|
||||
ND_COND, // ?:
|
||||
ND_COMMA, // ,
|
||||
ND_MEMBER, // . (struct member access)
|
||||
ND_ADDR, // unary &
|
||||
|
|
12
codegen.c
12
codegen.c
|
@ -205,6 +205,18 @@ static void gen_expr(Node *node) {
|
|||
gen_expr(node->lhs);
|
||||
cast(node->lhs->ty, node->ty);
|
||||
return;
|
||||
case ND_COND: {
|
||||
int c = count();
|
||||
gen_expr(node->cond);
|
||||
println(" cmp $0, %%rax");
|
||||
println(" je .L.else.%d", c);
|
||||
gen_expr(node->then);
|
||||
println(" jmp .L.end.%d", c);
|
||||
println(".L.else.%d:", c);
|
||||
gen_expr(node->els);
|
||||
println(".L.end.%d:", c);
|
||||
return;
|
||||
}
|
||||
case ND_NOT:
|
||||
gen_expr(node->lhs);
|
||||
println(" cmp $0, %%rax");
|
||||
|
|
22
parse.c
22
parse.c
|
@ -97,6 +97,7 @@ static Node *expr_stmt(Token **rest, Token *tok);
|
|||
static Node *expr(Token **rest, Token *tok);
|
||||
static Node *assign(Token **rest, Token *tok);
|
||||
static Node *logor(Token **rest, Token *tok);
|
||||
static Node *conditional(Token **rest, Token *tok);
|
||||
static Node *logand(Token **rest, Token *tok);
|
||||
static Node *bitor(Token **rest, Token *tok);
|
||||
static Node *bitxor(Token **rest, Token *tok);
|
||||
|
@ -849,11 +850,11 @@ static Node *to_assign(Node *binary) {
|
|||
return new_binary(ND_COMMA, expr1, expr2, tok);
|
||||
}
|
||||
|
||||
// assign = logor (assign-op assign)?
|
||||
// assign = conditional (assign-op assign)?
|
||||
// assign-op = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^="
|
||||
// | "<<=" | ">>="
|
||||
static Node *assign(Token **rest, Token *tok) {
|
||||
Node *node = logor(&tok, tok);
|
||||
Node *node = conditional(&tok, tok);
|
||||
|
||||
if (equal(tok, "="))
|
||||
return new_binary(ND_ASSIGN, node, assign(rest, tok->next), tok);
|
||||
|
@ -892,6 +893,23 @@ static Node *assign(Token **rest, Token *tok) {
|
|||
return node;
|
||||
}
|
||||
|
||||
// conditional = logor ("?" expr ":" conditional)?
|
||||
static Node *conditional(Token **rest, Token *tok) {
|
||||
Node *cond = logor(&tok, tok);
|
||||
|
||||
if (!equal(tok, "?")) {
|
||||
*rest = tok;
|
||||
return cond;
|
||||
}
|
||||
|
||||
Node *node = new_node(ND_COND, tok);
|
||||
node->cond = cond;
|
||||
node->then = expr(&tok, tok->next);
|
||||
tok = skip(tok, ":");
|
||||
node->els = conditional(rest, tok);
|
||||
return node;
|
||||
}
|
||||
|
||||
// logor = logand ("||" logand)*
|
||||
static Node *logor(Token **rest, Token *tok) {
|
||||
Node *node = logand(&tok, tok);
|
||||
|
|
13
test/arith.c
13
test/arith.c
|
@ -108,6 +108,19 @@ int main() {
|
|||
ASSERT(-1, ({ int i=-1; i; }));
|
||||
ASSERT(-1, ({ int i=-1; i>>=1; i; }));
|
||||
|
||||
ASSERT(2, 0?1:2);
|
||||
ASSERT(1, 1?1:2);
|
||||
ASSERT(-1, 0?-2:-1);
|
||||
ASSERT(-2, 1?-2:-1);
|
||||
ASSERT(4, sizeof(0?1:2));
|
||||
ASSERT(8, sizeof(0?(long)1:(long)2));
|
||||
ASSERT(-1, 0?(long)-2:-1);
|
||||
ASSERT(-1, 0?-2:(long)-1);
|
||||
ASSERT(-2, 1?(long)-2:-1);
|
||||
ASSERT(-2, 1?-2:(long)-1);
|
||||
|
||||
1 ? -2 : (void)-1;
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
8
type.c
8
type.c
|
@ -139,6 +139,14 @@ void add_type(Node *node) {
|
|||
case ND_VAR:
|
||||
node->ty = node->var->ty;
|
||||
return;
|
||||
case ND_COND:
|
||||
if (node->then->ty->kind == TY_VOID || node->els->ty->kind == TY_VOID) {
|
||||
node->ty = ty_void;
|
||||
} else {
|
||||
usual_arith_conv(&node->then, &node->els);
|
||||
node->ty = node->then->ty;
|
||||
}
|
||||
return;
|
||||
case ND_COMMA:
|
||||
node->ty = node->rhs->ty;
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue