Add |, & and ^ operators

This commit is contained in:
Rui Ueyama 2019-08-13 19:54:37 +09:00
parent 03acdd2ed9
commit 2586416967
5 changed files with 59 additions and 2 deletions

View File

@ -90,6 +90,9 @@ typedef enum {
ND_PTR_DIFF, // ptr - ptr
ND_MUL, // *
ND_DIV, // /
ND_BITAND, // &
ND_BITOR, // |
ND_BITXOR, // ^
ND_EQ, // ==
ND_NE, // !=
ND_LT, // <

View File

@ -152,6 +152,15 @@ static void gen_binary(Node *node) {
printf(" cqo\n");
printf(" idiv rdi\n");
break;
case ND_BITAND:
printf(" and rax, rdi\n");
break;
case ND_BITOR:
printf(" or rax, rdi\n");
break;
case ND_BITXOR:
printf(" xor rax, rdi\n");
break;
case ND_EQ:
printf(" cmp rax, rdi\n");
printf(" sete al\n");

34
parse.c
View File

@ -176,6 +176,9 @@ static Node *stmt(void);
static Node *stmt2(void);
static Node *expr(void);
static Node *assign(void);
static Node *bitand(void);
static Node *bitor(void);
static Node *bitxor(void);
static Node *equality(void);
static Node *relational(void);
static Node *add(void);
@ -742,10 +745,10 @@ static Node *expr(void) {
return node;
}
// assign = equality (assign-op assign)?
// assign = bitor (assign-op assign)?
// assign-op = "=" | "+=" | "-=" | "*=" | "/="
static Node *assign(void) {
Node *node = equality();
Node *node = bitor();
Token *tok;
if (tok = consume("="))
@ -776,6 +779,33 @@ static Node *assign(void) {
return node;
}
// bitor = bitxor ("|" bitxor)*
static Node *bitor(void) {
Node *node = bitxor();
Token *tok;
while (tok = consume("|"))
node = new_binary(ND_BITOR, node, bitxor(), tok);
return node;
}
// bitxor = bitand ("^" bitand)*
static Node *bitxor(void) {
Node *node = bitand();
Token *tok;
while (tok = consume("^"))
node = new_binary(ND_BITXOR, node, bitxor(), tok);
return node;
}
// bitand = equality ("&" equality)*
static Node *bitand(void) {
Node *node = equality();
Token *tok;
while (tok = consume("&"))
node = new_binary(ND_BITAND, node, equality(), tok);
return node;
}
// equality = relational ("==" relational | "!=" relational)*
static Node *equality(void) {
Node *node = relational();

12
tests
View File

@ -397,6 +397,18 @@ int main() {
assert(-1, ~0, "~0");
assert(0, ~-1, "~-1");
assert(0, 0&1, "0&1");
assert(1, 3&1, "3&1");
assert(3, 7&3, "7&3");
assert(10, -1&10, " -1&10");
assert(1, 0|1, "0|1");
assert(0b10011, 0b10000|0b00011, "01000|0b0011");
assert(0, 0^0, "0^0");
assert(0, 0b1111^0b1111, "0b1111^0b1111");
assert(0b110100, 0b111000^0b001100, "0b111000^0b001100");
printf("OK\n");
return 0;
}

3
type.c
View File

@ -71,6 +71,9 @@ void add_type(Node *node) {
case ND_PTR_DIFF:
case ND_MUL:
case ND_DIV:
case ND_BITAND:
case ND_BITOR:
case ND_BITXOR:
case ND_EQ:
case ND_NE:
case ND_LT: