implicit return 0 for main

This commit is contained in:
Yaossg 2024-11-30 09:40:52 +08:00
parent 4893f0cd68
commit 50969c6bb9
7 changed files with 36 additions and 27 deletions

View File

@ -135,7 +135,9 @@ $ sh boot.sh
- 不支持局部变量之间的遮挡,重名的局部变量为同一变量。
- 支持函数声明,可以通过函数声明来调用 C 语言库。不支持变量声明。
- 函数只支持最多八个参数。函数声明中支持可变参数,仅用于兼容 C 语言库。
- 类型检查可能有遗漏,若 C 编译器报错,而本语言编译通过,就可以认为是 UB。
- 类型检查有遗漏,若 C 编译器报错,而本语言编译通过,就可以认为是 UB。
- 例如函数调用的参数和 `return` 语句不会检查类型。
## 限制

54
boot.c
View File

@ -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);
}
@ -1048,7 +1060,7 @@ int parse_function_call(int id) {
asm_mv(rd, REG_A0);
return rd;
}
return -1;
return REG_ZERO;
}
int parse_primary_expr() {
@ -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;
}

View File

@ -2,5 +2,4 @@ int printf(const char* format, ...);
int main() {
printf("hello world %d\n", 42);
return 0;
}

View File

@ -43,5 +43,4 @@ int main() {
char ch;
while ((ch = getchar()) == '"') parse_string();
dump_string_table();
return 0;
}

View File

@ -43,5 +43,4 @@ void queen(int x) {
int main() {
queen(1);
printf("solutions: %d\n", a[0]);
return 0;
}

View File

@ -27,5 +27,4 @@ int main() {
printf("%d ", a[i]);
}
printf("\n");
return 0;
}

View File

@ -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;
}