From 2586416967029d2d38c79fe4b1307fe3e9d3dc55 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 13 Aug 2019 19:54:37 +0900 Subject: [PATCH] Add |, & and ^ operators --- chibi.h | 3 +++ codegen.c | 9 +++++++++ parse.c | 34 ++++++++++++++++++++++++++++++++-- tests | 12 ++++++++++++ type.c | 3 +++ 5 files changed, 59 insertions(+), 2 deletions(-) diff --git a/chibi.h b/chibi.h index 35cb9f8..b06d73f 100644 --- a/chibi.h +++ b/chibi.h @@ -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, // < diff --git a/codegen.c b/codegen.c index ff465cc..098d20a 100644 --- a/codegen.c +++ b/codegen.c @@ -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"); diff --git a/parse.c b/parse.c index 3a783b4..e091ee3 100644 --- a/parse.c +++ b/parse.c @@ -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(); diff --git a/tests b/tests index 81179c1..62c7ed1 100644 --- a/tests +++ b/tests @@ -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; } diff --git a/type.c b/type.c index da90b16..6fe5298 100644 --- a/type.c +++ b/type.c @@ -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: