aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-05-04 21:12:12 +0900
committernsfisis <nsfisis@gmail.com>2025-05-04 21:43:26 +0900
commit28c604c82bd76ec6bcbb0960ecadd706a6c20614 (patch)
tree3795417a3a765fab0b032c7b5fb1136a09af39ee
parent576b2064e05633b34de216e04b71407a5f15164b (diff)
downloadP4Dcc-28c604c82bd76ec6bcbb0960ecadd706a6c20614.tar.gz
P4Dcc-28c604c82bd76ec6bcbb0960ecadd706a6c20614.tar.zst
P4Dcc-28c604c82bd76ec6bcbb0960ecadd706a6c20614.zip
logical not expr
-rw-r--r--main.c18
-rw-r--r--tests/035.sh17
2 files changed, 34 insertions, 1 deletions
diff --git a/main.c b/main.c
index 5c240ac..7b3ae57 100644
--- a/main.c
+++ b/main.c
@@ -883,6 +883,12 @@ struct AstNode* parse_prefix_expr(struct Parser* p) {
struct AstNode* e = ast_new_binary_expr(op, lhs, operand);
e->ty = type_new(TY_INT);
return e;
+ } else if (op == TK_NOT) {
+ next_token(p);
+ struct AstNode* operand = parse_prefix_expr(p);
+ struct AstNode* e = ast_new_unary_expr(op, operand);
+ e->ty = type_new(TY_INT);
+ return e;
} else if (op == TK_AND) {
next_token(p);
struct AstNode* operand = parse_prefix_expr(p);
@@ -1439,7 +1445,17 @@ void gen_unary_expr(struct CodeGen* g, struct AstNode* ast) {
assert_ast_kind(ast, AST_UNARY_EXPR);
printf(" # gen_unary_expr\n");
- todo();
+ gen_expr(g, ast->expr1, GEN_RVAL);
+ if (ast->op == TK_NOT) {
+ printf(" pop rax\n");
+ printf(" mov rdi, 0\n");
+ printf(" cmp rax, rdi\n");
+ printf(" sete al\n");
+ printf(" movzb rax, al\n");
+ printf(" push rax\n");
+ } else {
+ todo();
+ }
}
void gen_ref_expr(struct CodeGen* g, struct AstNode* ast, int gen_mode) {
diff --git a/tests/035.sh b/tests/035.sh
new file mode 100644
index 0000000..a32709e
--- /dev/null
+++ b/tests/035.sh
@@ -0,0 +1,17 @@
+set -e
+
+cat <<'EOF' > expected
+0
+1
+0
+EOF
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+int main() {
+ printf("%d\n", !1);
+ printf("%d\n", !0);
+ printf("%d\n", !23);
+ return 0;
+}
+EOF