aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-02-05 01:38:34 -0500
committerMustafa Quraish <[email protected]>2022-02-05 08:56:15 -0500
commit81a0df76cbcd46799134e688dabb8dc870da5351 (patch)
treec272607d270b3ae8f1ba95cb6f6b28c9d0bc6075 /src
parentMiscellaneous stdlib additions (diff)
downloadcup-81a0df76cbcd46799134e688dabb8dc870da5351.tar.xz
cup-81a0df76cbcd46799134e688dabb8dc870da5351.zip
Add support for some more binary ops: |, &, ^
Diffstat (limited to 'src')
-rw-r--r--src/ast.c35
-rw-r--r--src/ast.h2
-rw-r--r--src/generator.c23
-rw-r--r--src/lexer.c1
-rw-r--r--src/parser.c11
-rw-r--r--src/tokens.h1
-rw-r--r--src/types.c3
7 files changed, 58 insertions, 18 deletions
diff --git a/src/ast.c b/src/ast.c
index 24885c2..9b392a9 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -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");
}
diff --git a/src/ast.h b/src/ast.h
index 0c8f70e..074228c 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -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);