mirror of https://github.com/rui314/chibicc
Add &, |, ^, &=, |= and ^=
This commit is contained in:
parent
daa739817c
commit
86440068b4
|
@ -97,6 +97,9 @@ typedef enum {
|
||||||
ND_DIV, // /
|
ND_DIV, // /
|
||||||
ND_NEG, // unary -
|
ND_NEG, // unary -
|
||||||
ND_MOD, // %
|
ND_MOD, // %
|
||||||
|
ND_BITAND, // &
|
||||||
|
ND_BITOR, // |
|
||||||
|
ND_BITXOR, // ^
|
||||||
ND_EQ, // ==
|
ND_EQ, // ==
|
||||||
ND_NE, // !=
|
ND_NE, // !=
|
||||||
ND_LT, // <
|
ND_LT, // <
|
||||||
|
|
|
@ -273,6 +273,15 @@ static void gen_expr(Node *node) {
|
||||||
if (node->kind == ND_MOD)
|
if (node->kind == ND_MOD)
|
||||||
println(" mov %%rdx, %%rax");
|
println(" mov %%rdx, %%rax");
|
||||||
return;
|
return;
|
||||||
|
case ND_BITAND:
|
||||||
|
println(" and %%rdi, %%rax");
|
||||||
|
return;
|
||||||
|
case ND_BITOR:
|
||||||
|
println(" or %%rdi, %%rax");
|
||||||
|
return;
|
||||||
|
case ND_BITXOR:
|
||||||
|
println(" xor %%rdi, %%rax");
|
||||||
|
return;
|
||||||
case ND_EQ:
|
case ND_EQ:
|
||||||
case ND_NE:
|
case ND_NE:
|
||||||
case ND_LT:
|
case ND_LT:
|
||||||
|
|
51
parse.c
51
parse.c
|
@ -77,6 +77,9 @@ static Node *stmt(Token **rest, Token *tok);
|
||||||
static Node *expr_stmt(Token **rest, Token *tok);
|
static Node *expr_stmt(Token **rest, Token *tok);
|
||||||
static Node *expr(Token **rest, Token *tok);
|
static Node *expr(Token **rest, Token *tok);
|
||||||
static Node *assign(Token **rest, Token *tok);
|
static Node *assign(Token **rest, Token *tok);
|
||||||
|
static Node *bitor(Token **rest, Token *tok);
|
||||||
|
static Node *bitxor(Token **rest, Token *tok);
|
||||||
|
static Node *bitand(Token **rest, Token *tok);
|
||||||
static Node *equality(Token **rest, Token *tok);
|
static Node *equality(Token **rest, Token *tok);
|
||||||
static Node *relational(Token **rest, Token *tok);
|
static Node *relational(Token **rest, Token *tok);
|
||||||
static Node *add(Token **rest, Token *tok);
|
static Node *add(Token **rest, Token *tok);
|
||||||
|
@ -696,10 +699,10 @@ static Node *to_assign(Node *binary) {
|
||||||
return new_binary(ND_COMMA, expr1, expr2, tok);
|
return new_binary(ND_COMMA, expr1, expr2, tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign = equality (assign-op assign)?
|
// assign = bitor (assign-op assign)?
|
||||||
// assign-op = "=" | "+=" | "-=" | "*=" | "/=" | "%="
|
// assign-op = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^="
|
||||||
static Node *assign(Token **rest, Token *tok) {
|
static Node *assign(Token **rest, Token *tok) {
|
||||||
Node *node = equality(&tok, tok);
|
Node *node = bitor(&tok, tok);
|
||||||
|
|
||||||
if (equal(tok, "="))
|
if (equal(tok, "="))
|
||||||
return new_binary(ND_ASSIGN, node, assign(rest, tok->next), tok);
|
return new_binary(ND_ASSIGN, node, assign(rest, tok->next), tok);
|
||||||
|
@ -719,6 +722,48 @@ static Node *assign(Token **rest, Token *tok) {
|
||||||
if (equal(tok, "%="))
|
if (equal(tok, "%="))
|
||||||
return to_assign(new_binary(ND_MOD, node, assign(rest, tok->next), tok));
|
return to_assign(new_binary(ND_MOD, node, assign(rest, tok->next), tok));
|
||||||
|
|
||||||
|
if (equal(tok, "&="))
|
||||||
|
return to_assign(new_binary(ND_BITAND, node, assign(rest, tok->next), tok));
|
||||||
|
|
||||||
|
if (equal(tok, "|="))
|
||||||
|
return to_assign(new_binary(ND_BITOR, node, assign(rest, tok->next), tok));
|
||||||
|
|
||||||
|
if (equal(tok, "^="))
|
||||||
|
return to_assign(new_binary(ND_BITXOR, node, assign(rest, tok->next), tok));
|
||||||
|
|
||||||
|
*rest = tok;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bitor = bitxor ("|" bitxor)*
|
||||||
|
static Node *bitor(Token **rest, Token *tok) {
|
||||||
|
Node *node = bitxor(&tok, tok);
|
||||||
|
while (equal(tok, "|")) {
|
||||||
|
Token *start = tok;
|
||||||
|
node = new_binary(ND_BITOR, node, bitxor(&tok, tok->next), start);
|
||||||
|
}
|
||||||
|
*rest = tok;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bitxor = bitand ("^" bitand)*
|
||||||
|
static Node *bitxor(Token **rest, Token *tok) {
|
||||||
|
Node *node = bitand(&tok, tok);
|
||||||
|
while (equal(tok, "^")) {
|
||||||
|
Token *start = tok;
|
||||||
|
node = new_binary(ND_BITXOR, node, bitand(&tok, tok->next), start);
|
||||||
|
}
|
||||||
|
*rest = tok;
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bitand = equality ("&" equality)*
|
||||||
|
static Node *bitand(Token **rest, Token *tok) {
|
||||||
|
Node *node = equality(&tok, tok);
|
||||||
|
while (equal(tok, "&")) {
|
||||||
|
Token *start = tok;
|
||||||
|
node = new_binary(ND_BITAND, node, equality(&tok, tok->next), start);
|
||||||
|
}
|
||||||
*rest = tok;
|
*rest = tok;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
16
test/arith.c
16
test/arith.c
|
@ -79,6 +79,22 @@ int main() {
|
||||||
ASSERT(2, ({ int i=10; i%=4; i; }));
|
ASSERT(2, ({ int i=10; i%=4; i; }));
|
||||||
ASSERT(2, ({ long i=10; i%=4; i; }));
|
ASSERT(2, ({ long i=10; i%=4; i; }));
|
||||||
|
|
||||||
|
ASSERT(0, 0&1);
|
||||||
|
ASSERT(1, 3&1);
|
||||||
|
ASSERT(3, 7&3);
|
||||||
|
ASSERT(10, -1&10);
|
||||||
|
|
||||||
|
ASSERT(1, 0|1);
|
||||||
|
ASSERT(0b10011, 0b10000|0b00011);
|
||||||
|
|
||||||
|
ASSERT(0, 0^0);
|
||||||
|
ASSERT(0, 0b1111^0b1111);
|
||||||
|
ASSERT(0b110100, 0b111000^0b001100);
|
||||||
|
|
||||||
|
ASSERT(2, ({ int i=6; i&=3; i; }));
|
||||||
|
ASSERT(7, ({ int i=6; i|=3; i; }));
|
||||||
|
ASSERT(10, ({ int i=15; i^=5; i; }));
|
||||||
|
|
||||||
printf("OK\n");
|
printf("OK\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ static int from_hex(char c) {
|
||||||
static int read_punct(char *p) {
|
static int read_punct(char *p) {
|
||||||
static char *kw[] = {
|
static char *kw[] = {
|
||||||
"==", "!=", "<=", ">=", "->", "+=", "-=", "*=", "/=", "++", "--",
|
"==", "!=", "<=", ">=", "->", "+=", "-=", "*=", "/=", "++", "--",
|
||||||
"%=",
|
"%=", "&=", "|=", "^=",
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++)
|
for (int i = 0; i < sizeof(kw) / sizeof(*kw); i++)
|
||||||
|
|
3
type.c
3
type.c
|
@ -99,6 +99,9 @@ void add_type(Node *node) {
|
||||||
case ND_MUL:
|
case ND_MUL:
|
||||||
case ND_DIV:
|
case ND_DIV:
|
||||||
case ND_MOD:
|
case ND_MOD:
|
||||||
|
case ND_BITAND:
|
||||||
|
case ND_BITOR:
|
||||||
|
case ND_BITXOR:
|
||||||
usual_arith_conv(&node->lhs, &node->rhs);
|
usual_arith_conv(&node->lhs, &node->rhs);
|
||||||
node->ty = node->lhs->ty;
|
node->ty = node->lhs->ty;
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue