feat add func call and rewrite codes

This commit is contained in:
ZZY
2025-03-07 12:29:53 +08:00
parent 09299e339c
commit 95bf44eb3f
37 changed files with 3369 additions and 1063 deletions

View File

@@ -1,27 +1,28 @@
#include "../parser.h"
#include "ast.h"
struct ASTNode* parse_stmt(struct Parser* parser) {
flushpeektok(parser);
enum TokenType ttype = peektoktype(parser);
struct ASTNode* node = new_ast_node();
ast_node_t* parse_stmt(parser_t* parser) {
tok_buf_t* tokbuf = &parser->tokbuf;
flush_peek_tok(tokbuf);
tok_type_t ttype = peek_tok_type(tokbuf);
ast_node_t* node = new_ast_node();
switch (ttype) {
case TOKEN_IF: {
/**
* if (exp) stmt
* if (exp) stmt else stmt
*/
poptok(parser);
pop_tok(tokbuf);
expecttok(parser, TOKEN_L_PAREN);
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
node->if_stmt.cond = parse_expr(parser);
flushpeektok(parser);
expecttok(parser, TOKEN_R_PAREN);
flush_peek_tok(tokbuf);
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
node->if_stmt.if_stmt = parse_stmt(parser);
ttype = peektoktype(parser);
ttype = peek_tok_type(tokbuf);
if (ttype == TOKEN_ELSE) {
poptok(parser);
pop_tok(tokbuf);
node->if_stmt.else_stmt = parse_stmt(parser);
} else {
node->if_stmt.else_stmt = NULL;
@@ -33,11 +34,11 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
/**
* switch (exp) stmt
*/
poptok(parser);
pop_tok(tokbuf);
expecttok(parser, TOKEN_L_PAREN);
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
node->switch_stmt.cond = parse_expr(parser);
expecttok(parser, TOKEN_R_PAREN);
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
node->switch_stmt.body = parse_stmt(parser);
node->type = NT_STMT_SWITCH;
@@ -47,11 +48,11 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
/**
* while (exp) stmt
*/
poptok(parser);
pop_tok(tokbuf);
expecttok(parser, TOKEN_L_PAREN);
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
node->while_stmt.cond = parse_expr(parser);
expecttok(parser, TOKEN_R_PAREN);
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
node->while_stmt.body = parse_stmt(parser);
node->type = NT_STMT_WHILE;
@@ -61,16 +62,16 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
/**
* do stmt while (exp)
*/
poptok(parser);
pop_tok(tokbuf);
node->do_while_stmt.body = parse_stmt(parser);
ttype = peektoktype(parser);
ttype = peek_tok_type(tokbuf);
if (ttype != TOKEN_WHILE) {
error("expected while after do");
}
poptok(parser);
expecttok(parser, TOKEN_L_PAREN);
pop_tok(tokbuf);
expect_pop_tok(tokbuf, TOKEN_L_PAREN);
node->do_while_stmt.cond = parse_expr(parser);
expecttok(parser, TOKEN_R_PAREN);
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
node->type = NT_STMT_DOWHILE;
break;
}
@@ -79,36 +80,36 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
* for (init; [cond]; [iter]) stmt
*/
// node->children.stmt.for_stmt.init
poptok(parser);
ttype = peektoktype(parser);
pop_tok(tokbuf);
ttype = peek_tok_type(tokbuf);
if (ttype != TOKEN_L_PAREN) {
error("expected ( after for");
}
poptok(parser);
pop_tok(tokbuf);
// init expr or init decl_var
// TODO need add this feature
node->for_stmt.init = parse_expr(parser);
expecttok(parser, TOKEN_SEMICOLON);
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
// cond expr or null
ttype = peektoktype(parser);
ttype = peek_tok_type(tokbuf);
if (ttype != TOKEN_SEMICOLON) {
node->for_stmt.cond = parse_expr(parser);
expecttok(parser, TOKEN_SEMICOLON);
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
} else {
node->for_stmt.cond = NULL;
poptok(parser);
pop_tok(tokbuf);
}
// iter expr or null
ttype = peektoktype(parser);
ttype = peek_tok_type(tokbuf);
if (ttype != TOKEN_R_PAREN) {
node->for_stmt.iter = parse_expr(parser);
expecttok(parser, TOKEN_R_PAREN);
expect_pop_tok(tokbuf, TOKEN_R_PAREN);
} else {
node->for_stmt.iter = NULL;
poptok(parser);
pop_tok(tokbuf);
}
node->for_stmt.body = parse_stmt(parser);
@@ -120,8 +121,8 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
* break ;
*/
// TODO check 导致外围 for、while 或 do-while 循环或 switch 语句终止。
poptok(parser);
expecttok(parser, TOKEN_SEMICOLON);
pop_tok(tokbuf);
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
node->type = NT_STMT_BREAK;
break;
@@ -131,8 +132,8 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
* continue ;
*/
// TODO check 导致跳过整个 for、 while 或 do-while 循环体的剩余部分。
poptok(parser);
expecttok(parser, TOKEN_SEMICOLON);
pop_tok(tokbuf);
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
node->type = NT_STMT_CONTINUE;
break;
@@ -142,16 +143,16 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
* return [exp] ;
*/
// TODO 终止当前函数并返回指定值给调用方函数。
poptok(parser);
ttype = peektoktype(parser);
pop_tok(tokbuf);
ttype = peek_tok_type(tokbuf);
if (ttype != TOKEN_SEMICOLON) {
node->return_stmt.expr_stmt = parse_expr(parser);
flushpeektok(parser);
expecttok(parser, TOKEN_SEMICOLON);
flush_peek_tok(tokbuf);
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
} else {
node->return_stmt.expr_stmt = NULL;
pop_tok(tokbuf);
}
poptok(parser);
node->type = NT_STMT_RETURN;
break;
}
@@ -161,15 +162,15 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
*/
// TODO check label 将控制无条件转移到所欲位置。
//在无法用约定的构造将控制转移到所欲位置时使用。
poptok(parser);
pop_tok(tokbuf);
// find symbol table
ttype = peektoktype(parser);
ttype = peek_tok_type(tokbuf);
if (ttype != TOKEN_IDENT) {
error("expect identifier after goto");
}
expecttok(parser, TOKEN_SEMICOLON);
expect_pop_tok(tokbuf, TOKEN_SEMICOLON);
// TODO filling label
node->goto_stmt.label = parse_ident(parser);
node->goto_stmt.label = expect_pop_ident(tokbuf);
node->type = NT_STMT_GOTO;
break;
}
@@ -181,7 +182,7 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
* if () ;
* for () ;
*/
poptok(parser);
pop_tok(tokbuf);
node->type = NT_STMT_EMPTY;
break;
}
@@ -193,30 +194,30 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
node->type = NT_STMT_BLOCK;
break;
}
case TOKEN_IDENT: {
case TOKEN_IDENT: {
// TODO label goto
if (peektoktype(parser) != TOKEN_COLON) {
if (peek_tok_type(tokbuf) != TOKEN_COLON) {
goto EXP;
}
node->label_stmt.label = parse_ident(parser);
expecttok(parser, TOKEN_COLON);
node->label_stmt.label = expect_pop_ident(tokbuf);
expect_pop_tok(tokbuf, TOKEN_COLON);
node->type = NT_STMT_LABEL;
break;
}
case TOKEN_CASE: {
// TODO label switch
poptok(parser);
pop_tok(tokbuf);
error("unimplemented switch label");
node->label_stmt.label = parse_expr(parser);
// TODO 该表达式为const int
expecttok(parser, TOKEN_COLON);
expect_pop_tok(tokbuf, TOKEN_COLON);
node->type = NT_STMT_CASE;
break;
}
case TOKEN_DEFAULT: {
// TODO label switch default
poptok(parser);
expecttok(parser, TOKEN_COLON);
pop_tok(tokbuf);
expect_pop_tok(tokbuf, TOKEN_COLON);
node->type = NT_STMT_DEFAULT;
break;
}
@@ -226,15 +227,16 @@ struct ASTNode* parse_stmt(struct Parser* parser) {
*/
EXP:
node->expr_stmt.expr_stmt = parse_expr(parser);
flushpeektok(parser);
ttype = peektoktype(parser);
flush_peek_tok(tokbuf);
ttype = peek_tok_type(tokbuf);
if (ttype != TOKEN_SEMICOLON) {
error("exp must end with \";\"");
}
poptok(parser);
pop_tok(tokbuf);
node->type = NT_STMT_EXPR;
break;
}
}
return node;
}