This commit is contained in:
Yaossg 2024-11-17 10:52:27 +08:00
parent dfbeb90387
commit 5670654667
2 changed files with 22 additions and 2 deletions

View File

@ -66,7 +66,7 @@ $ sh boot.sh
### 支持的流程控制 ### 支持的流程控制
- `if` `else` - `if` `else`
- `while` `for` - `while` `for` `do`
- `break` `continue` - `break` `continue`
- `return` - `return`

22
boot.c
View File

@ -68,6 +68,7 @@ const int TOKEN_VOID = 109;
const int TOKEN_CONST = 110; const int TOKEN_CONST = 110;
const int TOKEN_CHAR = 111; const int TOKEN_CHAR = 111;
const int TOKEN_FOR = 112; const int TOKEN_FOR = 112;
const int TOKEN_DO = 113;
const int TOKEN_STRING = 150; const int TOKEN_STRING = 150;
int parse_int(int ch) { int parse_int(int ch) {
@ -193,6 +194,8 @@ void parse_id_like(int ch) {
token_type = TOKEN_CHAR; token_type = TOKEN_CHAR;
} else if (streq(id, "for")) { } else if (streq(id, "for")) {
token_type = TOKEN_FOR; token_type = TOKEN_FOR;
} else if (streq(id, "do")) {
token_type = TOKEN_DO;
} }
if (token_type != TOKEN_ID) { if (token_type != TOKEN_ID) {
rewind_id(0); rewind_id(0);
@ -249,7 +252,7 @@ void next_token() {
} else if (ch == '/') { } else if (ch == '/') {
int ch2 = getchar(); int ch2 = getchar();
if (ch2 == '/') { if (ch2 == '/') {
while ((ch = getchar()) != -1 && ch != '\n'); do ch = getchar(); while (ch != -1 && ch != '\n');
next_token(); next_token();
return; return;
} else if (ch2 == '*') { } else if (ch2 == '*') {
@ -1174,6 +1177,21 @@ void parse_for() {
asm_pop_label(); asm_pop_label();
} }
void parse_do_while() {
int cont_label = next_label();
int break_label = next_label();
asm_push_label(break_label, cont_label);
asm_label(cont_label);
parse_stmt(); // body
expect_token(TOKEN_WHILE);
expect_token(TOKEN_PAREN_LEFT);
int cond = parse_expr();
asm_bnez(cond, cont_label);
expect_token(TOKEN_PAREN_RIGHT);
asm_label(break_label);
asm_pop_label();
}
void parse_stmt() { void parse_stmt() {
next_token(); next_token();
int decl_type; int decl_type;
@ -1186,6 +1204,8 @@ void parse_stmt() {
} else if (token_type == TOKEN_FOR) { } else if (token_type == TOKEN_FOR) {
parse_for(); parse_for();
return; return;
} else if (token_type == TOKEN_DO) {
parse_do_while();
} else if (token_type == TOKEN_BRACE_LEFT) { } else if (token_type == TOKEN_BRACE_LEFT) {
while (1) { while (1) {
next_token(); next_token();