Skip to content

Commit

Permalink
feat: add oprators
Browse files Browse the repository at this point in the history
  • Loading branch information
diohabara committed Jul 6, 2023
1 parent 34f1e65 commit fcc625f
Show file tree
Hide file tree
Showing 7 changed files with 359 additions and 27 deletions.
17 changes: 17 additions & 0 deletions ccc.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ typedef enum {
ND_LT, // <
ND_LE, // <=
ND_ASSIGN, // =
ND_COMMA, // ,
ND_RETURN, // "return"
ND_IF, // "if"
ND_WHILE, // "while"
Expand All @@ -94,6 +95,22 @@ typedef enum {
ND_SIZEOF, // "sizeof"
ND_MEMBER, // . (struct member access)
ND_CAST, // Type cast
ND_PRE_INC, // pre ++
ND_PRE_DEC, // pre --
ND_POST_INC, // post ++
ND_POST_DEC, // post --
ND_A_ADD, // +=
ND_A_SUB, // -=
ND_A_MUL, // *=
ND_A_DIV, // /=
ND_A_MOD, // %=
ND_NOT, // !
ND_BITNOT, // ~
ND_BITAND, // &
ND_BITOR, // |
ND_BITXOR, // ^
ND_LOGAND, // &&
ND_LOGOR, // ||
} NodeKind;
// AST node type
typedef struct Node Node;
Expand Down
145 changes: 144 additions & 1 deletion codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ void store(Type *ty) {
printf(" push rdi\n");
}

void inc(Type *ty) {
printf(" pop rax\n");
printf(" add rax, %d\n", ty->base ? size_of(ty->base) : 1);
printf(" push rax\n");
}

void dec(Type *ty) {
printf(" pop rax\n");
printf(" sub rax, %d\n", ty->base ? size_of(ty->base) : 1);
printf(" push rax\n");
}

// Generate code for a given node.
void gen(Node *node) {
switch (node->kind) {
Expand Down Expand Up @@ -131,6 +143,10 @@ void gen(Node *node) {
gen(node->rhs);
store(node->ty);
return;
case ND_COMMA:
gen(node->lhs);
gen(node->rhs);
return;
case ND_ADDR:
gen_addr(node->lhs);
return;
Expand All @@ -140,6 +156,40 @@ void gen(Node *node) {
load(node->ty);
}
return;
case ND_LOGAND: {
int seq = labelseq++;
gen(node->lhs);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" je .L.false.%d\n", seq);
gen(node->rhs);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" je .L.false.%d\n", seq);
printf(" push 1\n");
printf(" jmp .L.end.%d\n", seq);
printf(".L.false.%d:\n", seq);
printf(" push 0\n");
printf(".L.end.%d:\n", seq);
return;
}
case ND_LOGOR: {
int seq = labelseq++;
gen(node->lhs);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" jne .L.true.%d\n", seq);
gen(node->rhs);
printf(" pop rax\n");
printf(" cmp rax, 0\n");
printf(" jne .L.true.%d\n", seq);
printf(" push 0\n");
printf(" jmp .L.end.%d\n", seq);
printf(".L.true.%d:\n", seq);
printf(" push 1\n");
printf(".L.end.%d:\n", seq);
return;
}
case ND_IF: {
int seq = labelseq++;
if (node->els) {
Expand Down Expand Up @@ -233,6 +283,90 @@ void gen(Node *node) {
gen(node->lhs);
truncate(node->ty);
return;
case ND_PRE_INC:
gen_lval(node->lhs);
printf(" push [rsp]\n");
load(node->ty);
inc(node->ty);
store(node->ty);
return;
case ND_PRE_DEC:
gen_lval(node->lhs);
printf(" push [rsp]\n");
load(node->ty);
dec(node->ty);
store(node->ty);
return;
case ND_POST_INC:
gen_lval(node->lhs);
printf(" push [rsp]\n");
load(node->ty);
inc(node->ty);
store(node->ty);
dec(node->ty);
return;
case ND_POST_DEC:
gen_lval(node->lhs);
printf(" push [rsp]\n");
load(node->ty);
dec(node->ty);
store(node->ty);
inc(node->ty);
return;
case ND_A_ADD:
case ND_A_SUB:
case ND_A_MUL:
case ND_A_DIV:
case ND_A_MOD:
gen_lval(node->lhs);
printf(" push [rsp]\n");
load(node->ty);
gen(node->rhs);
printf(" pop rdi\n");
printf(" pop rax\n");
switch (node->kind) {
case ND_A_ADD:
if (node->ty->base) {
printf(" imul rdi, %d\n", size_of(node->ty->base));
}
printf(" add rax, rdi\n");
break;
case ND_A_SUB:
if (node->ty->base) {
printf(" imul rdi, %d\n", size_of(node->ty->base));
}
printf(" sub rax, rdi\n");
break;
case ND_A_MUL:
printf(" imul rax, rdi\n");
break;
case ND_A_DIV:
printf(" cqo\n");
printf(" idiv rdi\n");
break;
case ND_A_MOD:
printf(" cqo\n");
printf(" idiv rdi\n");
printf(" mov rax, rdx\n");
break;
}
printf(" push rax\n");
store(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_BITNOT:
gen(node->lhs);
printf(" pop rax\n");
printf(" not rax\n");
printf(" push rax\n");
return;
}

gen(node->lhs);
Expand Down Expand Up @@ -279,6 +413,15 @@ void gen(Node *node) {
printf(" setle al\n");
printf(" movzb rax, al\n");
break;
case ND_BITAND:
printf(" and rax, rdi\n");
break;
case ND_BITOR:
printf(" or rax, rdi\n");
break;
case ND_BITXOR:
printf(" xor rax, rdi\n");
break;
}
printf(" push rax\n");
}
Expand Down Expand Up @@ -345,4 +488,4 @@ void codegen(Program *prog) {
printf(".intel_syntax noprefix\n");
emit_data(prog);
emit_text(prog);
}
}
29 changes: 11 additions & 18 deletions examples/nqueen.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,23 @@
// $ ./tmp

int print_board(int (*board)[10]) {
for (int i = 0; i < 10; i=i+1) {
for (int j = 0; j < 10; j=j+1)
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++)
if (board[i][j])
printf("Q ");
printf("Q ");
else
printf(". ");
printf(". ");
printf("\n");
}
printf("\n\n");
}

int conflict(int (*board)[10], int row, int col) {
for (int i = 0; i < row; i=i+1) {
if (board[i][col])
return 1;
for (int i = 0; i < row; i++) {
if (board[i][col]) return 1;
int j = row - i;
if (0 < col - j + 1)
if (board[i][col - j])
return 1;
if (col + j < 10)
if (board[i][col + j])
return 1;
if (0 < col - j + 1 && board[i][col - j]) return 1;
if (col + j < 10 && board[i][col + j]) return 1;
}
return 0;
}
Expand All @@ -37,9 +32,8 @@ int solve(int (*board)[10], int row) {
print_board(board);
return 0;
}
for (int i = 0; i < 10; i=i+1) {
if (conflict(board, row, i)) {
} else {
for (int i = 0; i < 10; i++) {
if (!conflict(board, row, i)) {
board[row][i] = 1;
solve(board, row + 1);
board[row][i] = 0;
Expand All @@ -49,8 +43,7 @@ int solve(int (*board)[10], int row) {

int main() {
int board[100];
for (int i = 0; i < 100; i=i+1)
board[i] = 0;
for (int i = 0; i < 100; i++) board[i] = 0;
solve(board, 0);
return 0;
}
Loading

0 comments on commit fcc625f

Please sign in to comment.