Compare commits
3 Commits
3b95608233
...
5784a90d7e
Author | SHA1 | Date | |
---|---|---|---|
5784a90d7e | |||
a9054f0a64 | |||
9a2a1b00be |
@ -146,6 +146,7 @@ $ sh boot.sh
|
|||||||
|
|
||||||
### 其它支持与不支持
|
### 其它支持与不支持
|
||||||
|
|
||||||
|
- 不允许在一个声明中声明多个变量或函数(如 `int a, b;`)请写成多个声明。
|
||||||
- 支持全局变量和局部变量,局部变量遮挡全局变量。
|
- 支持全局变量和局部变量,局部变量遮挡全局变量。
|
||||||
- 不支持局部变量之间的遮挡,重名的局部变量为同一变量。
|
- 不支持局部变量之间的遮挡,重名的局部变量为同一变量。
|
||||||
- 函数只支持最多八个参数。函数声明中支持可变参数,仅用于兼容 C 语言库。
|
- 函数只支持最多八个参数。函数声明中支持可变参数,仅用于兼容 C 语言库。
|
||||||
|
27
boot.c
27
boot.c
@ -427,7 +427,7 @@ void next_token() {
|
|||||||
int ch2 = getchar();
|
int ch2 = getchar();
|
||||||
if (ch2 == '=') {
|
if (ch2 == '=') {
|
||||||
token_type = TOKEN_DIV_ASSIGN;
|
token_type = TOKEN_DIV_ASSIGN;
|
||||||
} if (ch2 == '/') {
|
} else if (ch2 == '/') {
|
||||||
do ch = getchar(); while (ch != -1 && ch != '\n');
|
do ch = getchar(); while (ch != -1 && ch != '\n');
|
||||||
next_token();
|
next_token();
|
||||||
return;
|
return;
|
||||||
@ -799,7 +799,14 @@ char* store_op_of_type(int type) {
|
|||||||
// address loaders
|
// address loaders
|
||||||
// rd must be one of t0, t1, t2
|
// rd must be one of t0, t1, t2
|
||||||
void load_local_address(int rd, int slot_id) {
|
void load_local_address(int rd, int slot_id) {
|
||||||
asm_addi(reg_name(rd), "sp", slot_id * 8 - 8);
|
int offset = slot_id * 8 - 8;
|
||||||
|
char* rd_name = reg_name(rd);
|
||||||
|
if (check_itype_immediate(offset)) {
|
||||||
|
printf(" addi %s, sp, %d\n", rd_name, offset);
|
||||||
|
} else {
|
||||||
|
printf(" li %s, %d\n", rd_name, offset);
|
||||||
|
printf(" add %s, sp, %s\n", rd_name, rd_name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load a non-trivial register into trivial one
|
// load a non-trivial register into trivial one
|
||||||
@ -1246,7 +1253,7 @@ int parse_postfix_expr() {
|
|||||||
int parse_prefix_expr() {
|
int parse_prefix_expr() {
|
||||||
next_token();
|
next_token();
|
||||||
if (token_type == TOKEN_AND) {
|
if (token_type == TOKEN_AND) {
|
||||||
int reg = parse_postfix_expr();
|
int reg = parse_prefix_expr();
|
||||||
int type = reg_type[reg];
|
int type = reg_type[reg];
|
||||||
if (type & TYPE_PTR_MASK) {
|
if (type & TYPE_PTR_MASK) {
|
||||||
fprintf(stderr, "cannot take address of a pointer\n");
|
fprintf(stderr, "cannot take address of a pointer\n");
|
||||||
@ -1254,7 +1261,7 @@ int parse_prefix_expr() {
|
|||||||
}
|
}
|
||||||
return addressof(reg);
|
return addressof(reg);
|
||||||
} else if (token_type == TOKEN_MUL) {
|
} else if (token_type == TOKEN_MUL) {
|
||||||
int reg = parse_postfix_expr();
|
int reg = parse_prefix_expr();
|
||||||
int type = reg_type[reg];
|
int type = reg_type[reg];
|
||||||
if (!(type & TYPE_PTR_MASK)) {
|
if (!(type & TYPE_PTR_MASK)) {
|
||||||
fprintf(stderr, "cannot dereference a non-pointer\n");
|
fprintf(stderr, "cannot dereference a non-pointer\n");
|
||||||
@ -1266,20 +1273,20 @@ int parse_prefix_expr() {
|
|||||||
}
|
}
|
||||||
return dereference(reg);
|
return dereference(reg);
|
||||||
} else if (token_type == TOKEN_SUB) {
|
} else if (token_type == TOKEN_SUB) {
|
||||||
int reg = parse_postfix_expr();
|
int reg = parse_prefix_expr();
|
||||||
return asm_r_arith("neg", reg);
|
return asm_r_arith("neg", reg);
|
||||||
} else if (token_type == TOKEN_COMPL) {
|
} else if (token_type == TOKEN_COMPL) {
|
||||||
int reg = parse_postfix_expr();
|
int reg = parse_prefix_expr();
|
||||||
return asm_r_arith("not", reg);
|
return asm_r_arith("not", reg);
|
||||||
} else if (token_type == TOKEN_NOT) {
|
} else if (token_type == TOKEN_NOT) {
|
||||||
int reg = parse_postfix_expr();
|
int reg = parse_prefix_expr();
|
||||||
return asm_r(TYPE_INT, "seqz", reg);
|
return asm_r(TYPE_INT, "seqz", reg);
|
||||||
} else if (token_type == TOKEN_INC) {
|
} else if (token_type == TOKEN_INC) {
|
||||||
int reg = parse_postfix_expr();
|
int reg = parse_prefix_expr();
|
||||||
_asm_ri("addi", reg, reg, step_of(reg_type[reg]));
|
_asm_ri("addi", reg, reg, step_of(reg_type[reg]));
|
||||||
return reg;
|
return reg;
|
||||||
} else if (token_type == TOKEN_DEC) {
|
} else if (token_type == TOKEN_DEC) {
|
||||||
int reg = parse_postfix_expr();
|
int reg = parse_prefix_expr();
|
||||||
_asm_ri("addi", reg, reg, -step_of(reg_type[reg]));
|
_asm_ri("addi", reg, reg, -step_of(reg_type[reg]));
|
||||||
return reg;
|
return reg;
|
||||||
} else {
|
} else {
|
||||||
@ -1982,8 +1989,6 @@ void dump_string_table() {
|
|||||||
printf("\\t");
|
printf("\\t");
|
||||||
} else if (ch == '\r') {
|
} else if (ch == '\r') {
|
||||||
printf("\\r");
|
printf("\\r");
|
||||||
} else if (ch == '\0') {
|
|
||||||
printf("\\0");
|
|
||||||
} else if (ch == '\\') {
|
} else if (ch == '\\') {
|
||||||
printf("\\\\");
|
printf("\\\\");
|
||||||
} else if (ch == '\'') {
|
} else if (ch == '\'') {
|
||||||
|
1
test.sh
1
test.sh
@ -15,6 +15,7 @@ for i in *.c; do
|
|||||||
rm $i.ans
|
rm $i.ans
|
||||||
else
|
else
|
||||||
echo "Test '$i' failed"
|
echo "Test '$i' failed"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
echo "Passed $succ/$all tests"
|
echo "Passed $succ/$all tests"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
enum {
|
enum {
|
||||||
A, B, C = 1, D, E = A, F
|
A, B, C = 1, D, E = A, F,
|
||||||
};
|
};
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
int getchar();
|
int getchar();
|
||||||
int putchar(int ch);
|
int putchar(int ch);
|
||||||
int printf(char* format, ...);
|
int fprintf(void* file, char* format, ...);
|
||||||
|
extern void* stdout;
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int ch;
|
char ch = 0["\t\r\""];;
|
||||||
while ((ch = getchar()) != -1) {
|
while ((ch = getchar()) != -1) {
|
||||||
if (ch == '\\') {
|
if (ch == '\\') {
|
||||||
ch = getchar();
|
ch = getchar();
|
||||||
@ -22,7 +24,7 @@ int main() {
|
|||||||
} else if (ch == '\"') {
|
} else if (ch == '\"') {
|
||||||
ch = '\"';
|
ch = '\"';
|
||||||
} else {
|
} else {
|
||||||
printf("unexpected escaped character: '\\%c'\n", ch);
|
fprintf(stdout, "unexpected escaped character: '\\%c'\n", ch);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
test/inc.c
Normal file
14
test/inc.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
int printf(char* format, ...);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int a = 4;
|
||||||
|
printf("a = %d\n", a);
|
||||||
|
printf("a++ = %d\n", a++);
|
||||||
|
printf("a = %d\n", a);
|
||||||
|
printf("++a = %d\n", ++a);
|
||||||
|
printf("a = %d\n", a);
|
||||||
|
printf("a-- = %d\n", a--);
|
||||||
|
printf("a = %d\n", a);
|
||||||
|
printf("--a = %d\n", --a);
|
||||||
|
printf("a = %d\n", a);
|
||||||
|
}
|
0
test/inc.in
Normal file
0
test/inc.in
Normal file
10
test/inc.out
Normal file
10
test/inc.out
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
a = 4
|
||||||
|
a++ = 4
|
||||||
|
a = 5
|
||||||
|
++a = 6
|
||||||
|
a = 6
|
||||||
|
a-- = 6
|
||||||
|
a = 5
|
||||||
|
--a = 4
|
||||||
|
a = 4
|
||||||
|
0
|
18
test/loop.c
18
test/loop.c
@ -81,7 +81,25 @@ void test_break() {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_nested() {
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
// For loop
|
||||||
|
printf("For loop:\n");
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
for (j = 0; j < 5; j++) {
|
||||||
|
if (i >= 2 && j >= 2 && i + j >= 5) {
|
||||||
|
return; // Exit nested loop via return
|
||||||
|
}
|
||||||
|
printf("(%d, %d) ", i, j);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
test_continue();
|
test_continue();
|
||||||
test_break();
|
test_break();
|
||||||
|
test_nested();
|
||||||
}
|
}
|
@ -10,4 +10,7 @@ While loop:
|
|||||||
0 1 2
|
0 1 2
|
||||||
Do-while loop:
|
Do-while loop:
|
||||||
0 1 2
|
0 1 2
|
||||||
0
|
For loop:
|
||||||
|
(0, 0) (0, 1) (0, 2) (0, 3) (0, 4)
|
||||||
|
(1, 0) (1, 1) (1, 2) (1, 3) (1, 4)
|
||||||
|
(2, 0) (2, 1) (2, 2) 0
|
||||||
|
@ -1,5 +1,41 @@
|
|||||||
int main() {
|
int printf(char* format, ...);
|
||||||
// int placeholder[1024];
|
|
||||||
int a = 1;
|
|
||||||
return (a=(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(0)))))))))))))))))))))), (a = a);
|
enum {
|
||||||
|
a = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
int get_20() {
|
||||||
|
return (a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(- -0)))))))))))))))))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
void dummy(int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7) {
|
||||||
|
a0 += a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 -= a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 *= a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 /= a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 %= a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 &= a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 |= a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 ^= a2;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 <<= a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
a0 >>= a1;
|
||||||
|
printf("%d\n", a0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
char placeholder[4096];
|
||||||
|
int a = 1;
|
||||||
|
dummy((a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(! !0))))))))))))))))))))), 3, a, a, a, a, a, a);
|
||||||
|
return (a=(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(a+(~ ~0)))))))))))))))))))))), (a = a);
|
||||||
}
|
}
|
||||||
|
@ -1 +1,11 @@
|
|||||||
|
23
|
||||||
|
20
|
||||||
|
60
|
||||||
|
20
|
||||||
|
2
|
||||||
|
2
|
||||||
|
3
|
||||||
|
2
|
||||||
|
16
|
||||||
|
2
|
||||||
20
|
20
|
||||||
|
17
test/short.c
Normal file
17
test/short.c
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
int printf(char* format, ...);
|
||||||
|
|
||||||
|
int f(int i) {
|
||||||
|
printf("f(%d)\n", i);
|
||||||
|
return i % 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
1 && f(1);
|
||||||
|
0 && f(2);
|
||||||
|
1 || f(3);
|
||||||
|
0 || f(4);
|
||||||
|
1 ? f(5) : f(6);
|
||||||
|
0 ? f(7) : f(8);
|
||||||
|
1 && f(9) || f(10);
|
||||||
|
0 && f(11) || f(12);
|
||||||
|
}
|
0
test/short.in
Normal file
0
test/short.in
Normal file
7
test/short.out
Normal file
7
test/short.out
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
f(1)
|
||||||
|
f(4)
|
||||||
|
f(5)
|
||||||
|
f(8)
|
||||||
|
f(9)
|
||||||
|
f(12)
|
||||||
|
0
|
29
test/sort.c
29
test/sort.c
@ -1,21 +1,40 @@
|
|||||||
int printf(char* format, ...);
|
int printf(char* format, ...);
|
||||||
int scanf(char* format, ...);
|
int scanf(char* format, ...);
|
||||||
|
int exit(int status);
|
||||||
|
|
||||||
|
void assert_eq(int expected, int actual) {
|
||||||
|
if (expected != actual) {
|
||||||
|
printf("expected: %d, actual: %d\n", expected, actual);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(int* a, int* b) {
|
||||||
|
int t = *a;
|
||||||
|
*a = *b;
|
||||||
|
*b = t;
|
||||||
|
}
|
||||||
|
|
||||||
void sort(int a[], int n) {
|
void sort(int a[], int n) {
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
for (int j = i + 1; j < n; j++) {
|
for (int j = i + 1; j < n; j++) {
|
||||||
if (a[i] > a[j]) {
|
if (a[i] > a[j]) {
|
||||||
int t = a[i];
|
swap(&a[i], &a[j]);
|
||||||
a[i] = a[j];
|
assert_eq(i - j, &a[i] - &a[j]);
|
||||||
a[j] = t;
|
assert_eq(j - i, &a[j] - &a[i]);
|
||||||
|
assert_eq(a[i], *(a + i));
|
||||||
|
assert_eq(i[a], *(i + a));
|
||||||
|
assert_eq(a[j - i], *(a + (j - i)));
|
||||||
|
assert_eq(j[a - i], *(j + (a - i)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int a[100];
|
||||||
|
int n;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
int n;
|
|
||||||
int a[100];
|
|
||||||
scanf("%d", &n);
|
scanf("%d", &n);
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
scanf("%d", &a[i]);
|
scanf("%d", &a[i]);
|
||||||
|
Loading…
Reference in New Issue
Block a user