diff --git a/README.md b/README.md index 7b37e2a..d703cc6 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,9 @@ $ sh boot.sh - 不支持局部变量之间的遮挡,重名的局部变量为同一变量。 - 支持函数声明,可以通过函数声明来调用 C 语言库。不支持变量声明。 - 函数只支持最多八个参数。函数声明中支持可变参数,仅用于兼容 C 语言库。 -- 类型检查可能有遗漏,若 C 编译器报错,而本语言编译通过,就可以认为是 UB。 +- 类型检查有遗漏,若 C 编译器报错,而本语言编译通过,就可以认为是 UB。 + - 例如函数调用的参数和 `return` 语句不会检查类型。 + ## 限制 diff --git a/boot.c b/boot.c index 8aa7128..40d1c70 100644 --- a/boot.c +++ b/boot.c @@ -430,20 +430,18 @@ int parse_type() { next_token(); ignore_const(); if (token_type == TOKEN_STAR) { + next_token(); ignore_const(); - return type | TYPE_PTR_MASK; + type = type | TYPE_PTR_MASK; } unget_token(); return type; - } else { - return -1; } + return -1; } // asm -int epilog_label; - int local_table[4096]; // id -> local id int next_local_id = 1; int max_local_id = 1; @@ -760,7 +758,7 @@ void _asm_ri(const char* op, int rd, int rs1, int imm) { } } -void _asm_branch(const char* op, int rs1, int label) { +void asm_branch(const char* op, int rs1, int label) { const char* rs1_name = trivialize(rs1, REG_T0); printf(" %s %s, L%d\n", op, rs1_name, label); } @@ -869,11 +867,11 @@ int asm_rr_cmp(const char* op, int rs1, int rs2) { } void asm_beqz(int rs1, int label) { - _asm_branch("beqz", rs1, label); + asm_branch("beqz", rs1, label); } void asm_bnez(int rs1, int label) { - _asm_branch("bnez", rs1, label); + asm_branch("bnez", rs1, label); } void asm_j(int label) { @@ -895,12 +893,20 @@ int cont_label_stack[4096]; int break_label_stack_size; int cont_label_stack_size; -int asm_get_break_label() { - return break_label_stack[break_label_stack_size - 1]; +void asm_break() { + if (break_label_stack_size == 0) { + eprintf("break without loop\n"); + exit(1); + } + asm_j(break_label_stack[break_label_stack_size - 1]); } -int asm_get_cont_label() { - return cont_label_stack[cont_label_stack_size - 1]; +void asm_continue() { + if (cont_label_stack_size == 0) { + eprintf("continue without loop\n"); + exit(1); + } + asm_j(cont_label_stack[cont_label_stack_size - 1]); } void asm_push_label(int break_label, int cont_label) { @@ -913,6 +919,12 @@ void asm_pop_label() { --cont_label_stack_size; } +int epilog_label; + +void asm_return() { + asm_j(epilog_label); +} + int log_step_of(int type) { return 2 * (type == TYPE_INT_PTR); } @@ -1515,19 +1527,17 @@ void parse_stmt() { } else if (token_type == TOKEN_RETURN) { next_token(); if (token_type == TOKEN_SEMICOLON) { - asm_j(epilog_label); + asm_return(); return; } unget_token(); int rs1 = parse_expr(); asm_mv(REG_A0, rs1); - asm_j(epilog_label); + asm_return(); } else if (token_type == TOKEN_BREAK) { - int label = asm_get_break_label(); - asm_j(label); + asm_break(); } else if (token_type == TOKEN_CONTINUE) { - int label = asm_get_cont_label(); - asm_j(label); + asm_continue(); } else if (token_type == TOKEN_SEMICOLON) { unget_token(); } else if ((decl_type = parse_type()) >= 0) { @@ -1614,7 +1624,10 @@ void parse_function(const char* name) { unget_token(); parse_stmt(); } - asm_j(epilog_label); + if (streq(name, "main")) { + asm_mv(REG_A0, REG_ZERO); + } + asm_return(); int reg_used = max_reg_id - REG_S2; if (reg_used > 14) reg_used = 14; int frame_size = (max_local_id - 1 + reg_used + 2) * 8; @@ -1752,5 +1765,4 @@ void dump_string_table() { int main() { parse_top_level(); dump_string_table(); - return 0; } diff --git a/demo/hello.c b/demo/hello.c index 4000513..c94a263 100644 --- a/demo/hello.c +++ b/demo/hello.c @@ -2,5 +2,4 @@ int printf(const char* format, ...); int main() { printf("hello world %d\n", 42); - return 0; } \ No newline at end of file diff --git a/demo/lut.c b/demo/lut.c index f5b23ba..b4ed157 100644 --- a/demo/lut.c +++ b/demo/lut.c @@ -43,5 +43,4 @@ int main() { char ch; while ((ch = getchar()) == '"') parse_string(); dump_string_table(); - return 0; } \ No newline at end of file diff --git a/demo/queen.c b/demo/queen.c index ac4a310..2789ed3 100644 --- a/demo/queen.c +++ b/demo/queen.c @@ -43,5 +43,4 @@ void queen(int x) { int main() { queen(1); printf("solutions: %d\n", a[0]); - return 0; } \ No newline at end of file diff --git a/demo/sort.c b/demo/sort.c index b1db39d..8248c54 100644 --- a/demo/sort.c +++ b/demo/sort.c @@ -27,5 +27,4 @@ int main() { printf("%d ", a[i]); } printf("\n"); - return 0; } \ No newline at end of file diff --git a/demo/strcmp.c b/demo/strcmp.c index 6d4793e..50fe8aa 100644 --- a/demo/strcmp.c +++ b/demo/strcmp.c @@ -13,5 +13,4 @@ int main() { const char* s2 = "world"; printf("%d\n", strcmp(s1, s2)); printf("%d\n", strcmp(s1 + 5, s2)); - return 0; } \ No newline at end of file