diff --git a/chibi.h b/chibi.h index 50d0f088..f2404ce9 100644 --- a/chibi.h +++ b/chibi.h @@ -109,6 +109,7 @@ typedef enum { ND_MEMBER, // . (struct member access) ND_ADDR, // unary & ND_DEREF, // unary * + ND_NOT, // ! ND_RETURN, // "return" ND_IF, // "if" ND_WHILE, // "while" diff --git a/codegen.c b/codegen.c index ffa88f41..6da620fb 100644 --- a/codegen.c +++ b/codegen.c @@ -260,6 +260,14 @@ static void gen(Node *node) { if (node->ty->kind != TY_ARRAY) load(node->ty); return; + case ND_NOT: + gen(node->lhs); + printf(" pop rax\n"); + printf(" cmp rax, 0\n"); + printf(" sete al\n"); + printf(" movzb rax, al\n"); + printf(" push rax\n"); + return; case ND_IF: { int seq = labelseq++; if (node->els) { diff --git a/examples/nqueen.c b/examples/nqueen.c index ce847e05..281ffa75 100644 --- a/examples/nqueen.c +++ b/examples/nqueen.c @@ -38,8 +38,7 @@ int solve(int (*board)[10], int row) { return 0; } for (int i = 0; i < 10; i++) { - if (conflict(board, row, i)) { - } else { + if (!conflict(board, row, i)) { board[row][i] = 1; solve(board, row + 1); board[row][i] = 0; diff --git a/parse.c b/parse.c index f045e89d..715caa9d 100644 --- a/parse.c +++ b/parse.c @@ -885,7 +885,7 @@ static Node *cast(void) { return unary(); } -// unary = ("+" | "-" | "*" | "&")? cast +// unary = ("+" | "-" | "*" | "&" | "!")? cast // | ("++" | "--") unary // | postfix static Node *unary(void) { @@ -898,6 +898,8 @@ static Node *unary(void) { return new_unary(ND_ADDR, cast(), tok); if (tok = consume("*")) return new_unary(ND_DEREF, cast(), tok); + if (tok = consume("!")) + return new_unary(ND_NOT, cast(), tok); if (tok = consume("++")) return new_unary(ND_PRE_INC, unary(), tok); if (tok = consume("--")) diff --git a/tests b/tests index 8121a0d3..2d25e4e3 100644 --- a/tests +++ b/tests @@ -390,6 +390,10 @@ int main() { assert(47, 0b101111, "0b101111"); assert(47, 0B101111, "0B101111"); + assert(0, !1, "!1"); + assert(0, !2, "!2"); + assert(1, !0, "!0"); + printf("OK\n"); return 0; } diff --git a/type.c b/type.c index 0bfcd9fd..fe69ec2f 100644 --- a/type.c +++ b/type.c @@ -76,6 +76,7 @@ void add_type(Node *node) { case ND_LT: case ND_LE: case ND_NUM: + case ND_NOT: node->ty = long_type; return; case ND_PTR_ADD: