implicit return 0 for main
This commit is contained in:
parent
4893f0cd68
commit
50969c6bb9
@ -135,7 +135,9 @@ $ sh boot.sh
|
||||
- 不支持局部变量之间的遮挡,重名的局部变量为同一变量。
|
||||
- 支持函数声明,可以通过函数声明来调用 C 语言库。不支持变量声明。
|
||||
- 函数只支持最多八个参数。函数声明中支持可变参数,仅用于兼容 C 语言库。
|
||||
- 类型检查可能有遗漏,若 C 编译器报错,而本语言编译通过,就可以认为是 UB。
|
||||
- 类型检查有遗漏,若 C 编译器报错,而本语言编译通过,就可以认为是 UB。
|
||||
- 例如函数调用的参数和 `return` 语句不会检查类型。
|
||||
|
||||
|
||||
## 限制
|
||||
|
||||
|
54
boot.c
54
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);
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
@ -2,5 +2,4 @@ int printf(const char* format, ...);
|
||||
|
||||
int main() {
|
||||
printf("hello world %d\n", 42);
|
||||
return 0;
|
||||
}
|
@ -43,5 +43,4 @@ int main() {
|
||||
char ch;
|
||||
while ((ch = getchar()) == '"') parse_string();
|
||||
dump_string_table();
|
||||
return 0;
|
||||
}
|
@ -43,5 +43,4 @@ void queen(int x) {
|
||||
int main() {
|
||||
queen(1);
|
||||
printf("solutions: %d\n", a[0]);
|
||||
return 0;
|
||||
}
|
@ -27,5 +27,4 @@ int main() {
|
||||
printf("%d ", a[i]);
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user