diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-05 01:38:34 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-05 08:56:15 -0500 |
| commit | 81a0df76cbcd46799134e688dabb8dc870da5351 (patch) | |
| tree | c272607d270b3ae8f1ba95cb6f6b28c9d0bc6075 /src | |
| parent | Miscellaneous stdlib additions (diff) | |
| download | cup-81a0df76cbcd46799134e688dabb8dc870da5351.tar.xz cup-81a0df76cbcd46799134e688dabb8dc870da5351.zip | |
Add support for some more binary ops: |, &, ^
Diffstat (limited to 'src')
| -rw-r--r-- | src/ast.c | 35 | ||||
| -rw-r--r-- | src/ast.h | 2 | ||||
| -rw-r--r-- | src/generator.c | 23 | ||||
| -rw-r--r-- | src/lexer.c | 1 | ||||
| -rw-r--r-- | src/parser.c | 11 | ||||
| -rw-r--r-- | src/tokens.h | 1 | ||||
| -rw-r--r-- | src/types.c | 3 |
7 files changed, 58 insertions, 18 deletions
@@ -22,22 +22,25 @@ NodeType binary_token_to_op(TokenType type) { switch (type) { - case TOKEN_PLUS: return OP_PLUS; - case TOKEN_MINUS: return OP_MINUS; - case TOKEN_STAR: return OP_MUL; - case TOKEN_SLASH: return OP_DIV; - case TOKEN_PERCENT: return OP_MOD; - case TOKEN_LSHIFT: return OP_LSHIFT; - case TOKEN_RSHIFT: return OP_RSHIFT; - case TOKEN_AND: return OP_AND; - case TOKEN_OR: return OP_OR; - case TOKEN_XOR: return OP_XOR; - case TOKEN_EQ: return OP_EQ; - case TOKEN_NEQ: return OP_NEQ; - case TOKEN_LT: return OP_LT; - case TOKEN_LEQ: return OP_LEQ; - case TOKEN_GT: return OP_GT; - case TOKEN_GEQ: return OP_GEQ; + case TOKEN_PLUS: return OP_PLUS; + case TOKEN_MINUS: return OP_MINUS; + case TOKEN_STAR: return OP_MUL; + case TOKEN_SLASH: return OP_DIV; + case TOKEN_PERCENT: return OP_MOD; + case TOKEN_LSHIFT: return OP_LSHIFT; + case TOKEN_RSHIFT: return OP_RSHIFT; + case TOKEN_AND: return OP_AND; + case TOKEN_OR: return OP_OR; + case TOKEN_XOR: return OP_XOR; + case TOKEN_EQ: return OP_EQ; + case TOKEN_NEQ: return OP_NEQ; + case TOKEN_LT: return OP_LT; + case TOKEN_LEQ: return OP_LEQ; + case TOKEN_GT: return OP_GT; + case TOKEN_GEQ: return OP_GEQ; + case TOKEN_AMPERSAND: return OP_BWAND; + case TOKEN_BAR: return OP_BWOR; + case TOKEN_CARET: return OP_XOR; default: assert(false && "binary_token_to_op called with invalid token type"); } @@ -17,7 +17,9 @@ F(OP_LSHIFT, "<<") \ F(OP_RSHIFT, ">>") \ F(OP_AND, "&&") \ + F(OP_BWAND, "&") \ F(OP_OR, "||") \ + F(OP_BWOR, "|") \ F(OP_XOR, "^") \ F(OP_EQ, "==") \ F(OP_NEQ, "!=") \ diff --git a/src/generator.c b/src/generator.c index f5ae850..23cc315 100644 --- a/src/generator.c +++ b/src/generator.c @@ -256,6 +256,27 @@ void generate_expr_into_rax(Node *expr, FILE *out) fprintf(out, " setge al\n"); fprintf(out, " movzx rax, al\n"); + } else if (expr->type == OP_BWAND) { + generate_expr_into_rax(expr->binary.right, out); + fprintf(out, " push rax\n"); + generate_expr_into_rax(expr->binary.left, out); + fprintf(out, " pop rbx\n"); + fprintf(out, " and rax, rbx\n"); + + } else if (expr->type == OP_BWOR) { + generate_expr_into_rax(expr->binary.right, out); + fprintf(out, " push rax\n"); + generate_expr_into_rax(expr->binary.left, out); + fprintf(out, " pop rbx\n"); + fprintf(out, " or rax, rbx\n"); + + } else if (expr->type == OP_XOR) { + generate_expr_into_rax(expr->binary.right, out); + fprintf(out, " push rax\n"); + generate_expr_into_rax(expr->binary.left, out); + fprintf(out, " pop rbx\n"); + fprintf(out, " xor rax, rbx\n"); + // Note: These are different because of short-circuit evaluation! } else if (expr->type == OP_OR) { generate_expr_into_rax(expr->binary.left, out); @@ -287,7 +308,7 @@ void generate_expr_into_rax(Node *expr, FILE *out) fprintf(out, ".and_end_%d:\n", label_counter); label_counter++; - } else if (expr->type == AST_CONDITIONAL) { + } else if (expr->type == AST_CONDITIONAL) { int cur_label = label_counter++; generate_expr_into_rax(expr->conditional.cond, out); // If left is false, we can short-circuit diff --git a/src/lexer.c b/src/lexer.c index 83bd976..a5b1a42 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -128,6 +128,7 @@ Token Lexer_next(Lexer *lexer) case ':': return Lexer_make_token(lexer, TOKEN_COLON, 1); case '~': return Lexer_make_token(lexer, TOKEN_TILDE, 1); case '?': return Lexer_make_token(lexer, TOKEN_QUESTION, 1); + case '^': return Lexer_make_token(lexer, TOKEN_CARET, 1); case '.': return Lexer_make_token(lexer, TOKEN_DOT, 1); case ',': return Lexer_make_token(lexer, TOKEN_COMMA, 1); case '*': return Lexer_make_token(lexer, TOKEN_STAR, 1); diff --git a/src/parser.c b/src/parser.c index 99926d0..9f66060 100644 --- a/src/parser.c +++ b/src/parser.c @@ -651,8 +651,17 @@ Node *parse_relational(Lexer *lexer) { BINOP_PARSER(parse_additive, is_relationa bool is_equality_token(TokenType type) { return type == TOKEN_EQ || type == TOKEN_NEQ; } Node *parse_equality(Lexer *lexer) { BINOP_PARSER(parse_relational, is_equality_token); } +bool is_and_token(TokenType type) { return type == TOKEN_AMPERSAND; } +Node *parse_and(Lexer *lexer) { BINOP_PARSER(parse_equality, is_and_token); } + +bool is_exclusive_or_token(TokenType type) { return type == TOKEN_CARET; } +Node *parse_exclusive_or(Lexer *lexer) { BINOP_PARSER(parse_and, is_exclusive_or_token); } + +bool is_inclusive_or_token(TokenType type) { return type == TOKEN_BAR; } +Node *parse_inclusive_or(Lexer *lexer) { BINOP_PARSER(parse_exclusive_or, is_inclusive_or_token); } + bool is_logical_and_token(TokenType type) { return type == TOKEN_AND; } -Node *parse_logical_and(Lexer *lexer) { BINOP_PARSER(parse_equality, is_logical_and_token); } +Node *parse_logical_and(Lexer *lexer) { BINOP_PARSER(parse_inclusive_or, is_logical_and_token); } bool is_logical_or_token(TokenType type) { return type == TOKEN_OR; } Node *parse_logical_or(Lexer *lexer) { BINOP_PARSER(parse_logical_and, is_logical_or_token); } diff --git a/src/tokens.h b/src/tokens.h index 3fe5719..cde3a18 100644 --- a/src/tokens.h +++ b/src/tokens.h @@ -8,6 +8,7 @@ F(TOKEN_AND, "&&") \ F(TOKEN_ASSIGN, "=") \ F(TOKEN_BAR, "|") \ + F(TOKEN_CARET, "^") \ F(TOKEN_CHARLIT, "char literal") \ F(TOKEN_CLOSE_BRACE, "}") \ F(TOKEN_CLOSE_BRACKET, "]") \ diff --git a/src/types.c b/src/types.c index c44f88d..c8a9b72 100644 --- a/src/types.c +++ b/src/types.c @@ -298,6 +298,9 @@ Node *handle_binary_expr_types(Node *node, Token *token) case OP_GT: case OP_LEQ: case OP_GEQ: + case OP_BWAND: + case OP_BWOR: + case OP_XOR: case OP_AND: case OP_OR: { node->expr_type = type_new(TYPE_INT); |