diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-07-29 08:51:00 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-08-15 10:04:36 +0900 |
| commit | f30a6e048ccadd33c889caaa8012cfabfd5c2da9 (patch) | |
| tree | d64763931b2013024feb8505785840d47c51a03f | |
| parent | bfd0e04870c7cc55e8c2a9ee5e7b3e39fc9286c2 (diff) | |
| download | ducc-f30a6e048ccadd33c889caaa8012cfabfd5c2da9.tar.gz ducc-f30a6e048ccadd33c889caaa8012cfabfd5c2da9.tar.zst ducc-f30a6e048ccadd33c889caaa8012cfabfd5c2da9.zip | |
feat: implement bitwise or
| -rw-r--r-- | codegen.c | 2 | ||||
| -rw-r--r-- | parse.c | 20 | ||||
| -rw-r--r-- | preprocess.c | 14 | ||||
| -rw-r--r-- | tests/067.sh | 15 | ||||
| -rw-r--r-- | tokenize.c | 5 |
5 files changed, 50 insertions, 6 deletions
@@ -152,6 +152,8 @@ void codegen_binary_expr(CodeGen* g, AstNode* ast, GenMode gen_mode) { printf(" cqo\n"); printf(" idiv rdi\n"); printf(" mov rax, rdx\n"); + } else if (ast->node_op == TokenKind_or) { + printf(" or rax, rdi\n"); } else if (ast->node_op == TokenKind_eq) { printf(" cmp rax, rdi\n"); printf(" sete al\n"); @@ -474,13 +474,29 @@ AstNode* parse_equality_expr(Parser* p) { return lhs; } -AstNode* parse_logical_and_expr(Parser* p) { +AstNode* parse_bitwise_or_expr(Parser* p) { AstNode* lhs = parse_equality_expr(p); while (1) { TokenKind op = peek_token(p)->kind; - if (op == TokenKind_andand) { + if (op == TokenKind_or) { next_token(p); AstNode* rhs = parse_equality_expr(p); + lhs = ast_new_binary_expr(op, lhs, rhs); + lhs->ty = type_new(TypeKind_int); + } else { + break; + } + } + return lhs; +} + +AstNode* parse_logical_and_expr(Parser* p) { + AstNode* lhs = parse_bitwise_or_expr(p); + while (1) { + TokenKind op = peek_token(p)->kind; + if (op == TokenKind_andand) { + next_token(p); + AstNode* rhs = parse_bitwise_or_expr(p); AstNode* e = ast_new(AstNodeKind_logical_expr); e->node_op = op; e->node_lhs = lhs; diff --git a/preprocess.c b/preprocess.c index 4ffe12e..7fa98f3 100644 --- a/preprocess.c +++ b/preprocess.c @@ -146,10 +146,16 @@ void pp_tokenize_all(Preprocessor* pp) { tok->raw.data = pp->src + pp->pos - tok->raw.len; } } else if (c == '|') { - ++pp->pos; - tok->kind = PpTokenKind_punctuator; - tok->raw.len = 2; - tok->raw.data = pp->src + pp->pos - tok->raw.len; + if (pp->src[pp->pos] == '|') { + ++pp->pos; + tok->kind = PpTokenKind_punctuator; + tok->raw.len = 2; + tok->raw.data = pp->src + pp->pos - tok->raw.len; + } else { + tok->kind = PpTokenKind_punctuator; + tok->raw.len = 1; + tok->raw.data = pp->src + pp->pos - tok->raw.len; + } } else if (c == '&') { if (pp->src[pp->pos] == '&') { ++pp->pos; diff --git a/tests/067.sh b/tests/067.sh new file mode 100644 index 0000000..0abac88 --- /dev/null +++ b/tests/067.sh @@ -0,0 +1,15 @@ +set -e + +cat <<'EOF' > expected +123 +460 +EOF + +bash ../../test_diff.sh <<'EOF' +int printf(); + +int main() { + printf("%d\n", 0 | 123); + printf("%d\n", 12 | 456); +} +EOF @@ -44,6 +44,7 @@ enum TokenKind { TokenKind_minusminus, TokenKind_ne, TokenKind_not, + TokenKind_or, TokenKind_oror, TokenKind_paren_l, TokenKind_paren_r, @@ -154,6 +155,8 @@ const char* token_kind_stringify(TokenKind k) { return "!="; else if (k == TokenKind_not) return "!"; + else if (k == TokenKind_or) + return "|"; else if (k == TokenKind_oror) return "||"; else if (k == TokenKind_paren_l) @@ -316,6 +319,8 @@ void tokenize_all(Lexer* l) { tok->kind = TokenKind_plus; } else if (string_equals_cstr(&pp_tok->raw, "||")) { tok->kind = TokenKind_oror; + } else if (string_equals_cstr(&pp_tok->raw, "|")) { + tok->kind = TokenKind_or; } else if (string_equals_cstr(&pp_tok->raw, "&&")) { tok->kind = TokenKind_andand; } else if (string_equals_cstr(&pp_tok->raw, "&")) { |
