feat(ast): 添加内置类型定义和AST节点初始化函数
添加了完整的内置类型支持,包括整数、浮点数、字符、布尔等基本类型, 以及它们的有符号/无符号变体。同时添加了大量的AST节点初始化函数, 简化了AST节点的创建过程。 BREAKING CHANGE: 重构了AST表达式和声明结构,移除了冗余字段, 统一了命名规范,并修改了函数调用和成员访问的表示方式。
This commit is contained in:
@@ -51,9 +51,9 @@ A.2.3 Statements
|
||||
#include <scc_parser.h>
|
||||
static inline scc_ast_stmt_t *ast_stmt_alloc() {
|
||||
scc_ast_stmt_t *stmt = (scc_ast_stmt_t *)scc_malloc(sizeof(scc_ast_stmt_t));
|
||||
Assert(stmt != null);
|
||||
stmt->base.type = SCC_AST_UNKNOWN;
|
||||
stmt->base.loc = scc_pos_create();
|
||||
if (stmt == null) {
|
||||
LOG_FATAL("Out of memory");
|
||||
}
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -87,10 +87,7 @@ static scc_ast_stmt_t *parse_label_statement(scc_parser_t *parser) {
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
Assert(stmt != null);
|
||||
|
||||
stmt->base.type = SCC_AST_STMT_LABEL;
|
||||
stmt->label_stmt.label = scc_cstring_as_cstr(&tok.lexeme);
|
||||
stmt->label_stmt.stmt = statement;
|
||||
scc_ast_stmt_label_init(stmt, scc_cstring_as_cstr(&tok.lexeme), statement);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -113,10 +110,7 @@ static scc_ast_stmt_t *parse_case_statement(scc_parser_t *parser) {
|
||||
}
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
Assert(stmt != null);
|
||||
stmt->case_stmt.expr = expr;
|
||||
stmt->base.type = SCC_AST_STMT_CASE;
|
||||
stmt->case_stmt.stmt = statement;
|
||||
scc_ast_stmt_case_init(stmt, expr, statement);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -134,11 +128,9 @@ static scc_ast_stmt_t *parse_default_statement(scc_parser_t *parser) {
|
||||
if (statement == null) {
|
||||
Panic("expect stmt");
|
||||
}
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
Assert(stmt != null);
|
||||
stmt->base.type = SCC_AST_STMT_DEFAULT;
|
||||
stmt->default_stmt.stmt = statement;
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
scc_ast_stmt_default_init(stmt, statement);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -146,10 +138,9 @@ static scc_ast_stmt_t *parse_compound_statement(scc_parser_t *parser) {
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_L_BRACE)) {
|
||||
return null;
|
||||
}
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
stmt->base.type = SCC_AST_STMT_COMPOUND;
|
||||
scc_ast_block_item_vec_t block_items;
|
||||
scc_vec_init(block_items);
|
||||
|
||||
scc_vec_init(stmt->compound.block_items);
|
||||
while (!scc_parser_consume_if(parser, SCC_TOK_R_BRACE)) {
|
||||
/// TODO
|
||||
// scc_parse_is_decl();
|
||||
@@ -160,12 +151,15 @@ static scc_ast_stmt_t *parse_compound_statement(scc_parser_t *parser) {
|
||||
}
|
||||
if (ret == null) {
|
||||
LOG_ERROR("Invalid statement");
|
||||
// TODO
|
||||
scc_free(stmt);
|
||||
// TODO free
|
||||
parser->errcode = 1;
|
||||
return null;
|
||||
}
|
||||
scc_vec_push(stmt->compound.block_items, ret);
|
||||
scc_vec_push(block_items, ret);
|
||||
}
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
scc_ast_stmt_compound_init(stmt, &block_items);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -176,16 +170,16 @@ static scc_ast_stmt_t *parse_if_statement(scc_parser_t *parser) {
|
||||
|
||||
scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
|
||||
scc_ast_stmt_t *statement = scc_parse_statement(parser);
|
||||
scc_ast_stmt_t *opt_else = null;
|
||||
|
||||
if (scc_parser_consume_if(parser, SCC_TOK_ELSE)) {
|
||||
opt_else = scc_parse_statement(parser);
|
||||
} else {
|
||||
opt_else = null;
|
||||
}
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
stmt->base.type = SCC_AST_STMT_IF;
|
||||
stmt->if_stmt.cond = expression;
|
||||
stmt->if_stmt.then_stmt = statement;
|
||||
if (scc_parser_consume_if(parser, SCC_TOK_ELSE)) {
|
||||
stmt->if_stmt.opt_else_stmt = scc_parse_statement(parser);
|
||||
} else {
|
||||
stmt->if_stmt.opt_else_stmt = null;
|
||||
}
|
||||
scc_ast_stmt_if_init(stmt, expression, statement, opt_else);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -198,9 +192,7 @@ static scc_ast_stmt_t *parse_switch_statement(scc_parser_t *parser) {
|
||||
scc_ast_stmt_t *statement = scc_parse_statement(parser);
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
stmt->base.type = SCC_AST_STMT_SWITCH;
|
||||
stmt->switch_stmt.cond = expression;
|
||||
stmt->switch_stmt.body = statement;
|
||||
scc_ast_stmt_switch_init(stmt, expression, statement);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -213,9 +205,7 @@ static scc_ast_stmt_t *parse_while_statement(scc_parser_t *parser) {
|
||||
scc_ast_stmt_t *statement = scc_parse_statement(parser);
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
stmt->base.type = SCC_AST_STMT_WHILE;
|
||||
stmt->while_stmt.cond = expression;
|
||||
stmt->while_stmt.body = statement;
|
||||
scc_ast_stmt_while_init(stmt, expression, statement);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -235,9 +225,7 @@ static scc_ast_stmt_t *parse_do_while_statement(scc_parser_t *parser) {
|
||||
scc_ast_expr_t *expression = ast_parse_paren_expression(parser);
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
stmt->base.type = SCC_AST_STMT_DO_WHILE;
|
||||
stmt->do_while_stmt.cond = expression;
|
||||
stmt->do_while_stmt.body = statement;
|
||||
scc_ast_stmt_do_while_init(stmt, expression, statement);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -255,15 +243,17 @@ static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser) {
|
||||
LOG_ERROR("Expected '(' before like `( expression )` .");
|
||||
}
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
stmt->base.type = SCC_AST_STMT_FOR;
|
||||
scc_ast_type_t *init = null;
|
||||
scc_ast_expr_t *cond = null;
|
||||
scc_ast_expr_t *incr = null;
|
||||
scc_ast_stmt_t *body = null;
|
||||
|
||||
// TODO use decl or expr
|
||||
stmt->for_stmt.init = (scc_ast_type_t *)scc_parse_expression(parser);
|
||||
if (stmt->for_stmt.init == null) {
|
||||
stmt->for_stmt.init = (scc_ast_type_t *)scc_parse_declaration(parser);
|
||||
init = (scc_ast_type_t *)scc_parse_expression(parser);
|
||||
if (init == null) {
|
||||
init = (scc_ast_type_t *)scc_parse_declaration(parser);
|
||||
}
|
||||
if (stmt->for_stmt.init == null) {
|
||||
if (init == null) {
|
||||
LOG_ERROR("Expected expression or declaration in for statement.");
|
||||
}
|
||||
|
||||
@@ -271,20 +261,22 @@ static scc_ast_stmt_t *parse_for_statement(scc_parser_t *parser) {
|
||||
LOG_ERROR("Expected semicolon in for statement.");
|
||||
}
|
||||
|
||||
stmt->for_stmt.cond = scc_parse_expression(parser);
|
||||
cond = scc_parse_expression(parser);
|
||||
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
|
||||
LOG_ERROR("Expected semicolon in for statement.");
|
||||
}
|
||||
|
||||
stmt->for_stmt.iter = scc_parse_expression(parser);
|
||||
incr = scc_parse_expression(parser);
|
||||
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_R_PAREN)) {
|
||||
LOG_ERROR("Expected ')' after like `( expression )` .");
|
||||
}
|
||||
|
||||
stmt->for_stmt.body = scc_parse_statement(parser);
|
||||
body = scc_parse_statement(parser);
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
scc_ast_stmt_for_init(stmt, init, cond, incr, body);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@@ -292,20 +284,18 @@ static scc_ast_stmt_t *parse_jump_statement(scc_parser_t *parser) {
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
|
||||
if (scc_parser_consume_if(parser, SCC_TOK_GOTO)) {
|
||||
stmt->base.type = SCC_AST_STMT_GOTO;
|
||||
scc_lexer_tok_t tok = {0};
|
||||
if (scc_parser_next_consume(parser, &tok)) {
|
||||
stmt->goto_stmt.label = scc_cstring_as_cstr(&tok.lexeme);
|
||||
scc_ast_stmt_goto_init(stmt, scc_cstring_as_cstr(&tok.lexeme));
|
||||
} else {
|
||||
LOG_ERROR("Expected label after goto.");
|
||||
}
|
||||
} else if (scc_parser_consume_if(parser, SCC_TOK_CONTINUE)) {
|
||||
stmt->base.type = SCC_AST_STMT_CONTINUE;
|
||||
scc_ast_stmt_continue_init(stmt);
|
||||
} else if (scc_parser_consume_if(parser, SCC_TOK_BREAK)) {
|
||||
stmt->base.type = SCC_AST_STMT_BREAK;
|
||||
scc_ast_stmt_break_init(stmt);
|
||||
} else if (scc_parser_consume_if(parser, SCC_TOK_RETURN)) {
|
||||
stmt->base.type = SCC_AST_STMT_RETURN;
|
||||
stmt->return_stmt.expr = scc_parse_expression(parser);
|
||||
scc_ast_stmt_return_init(stmt, scc_parse_expression(parser));
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
@@ -317,21 +307,19 @@ static scc_ast_stmt_t *parse_jump_statement(scc_parser_t *parser) {
|
||||
}
|
||||
|
||||
static scc_ast_stmt_t *parse_expression_statement(scc_parser_t *parser) {
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
stmt->base.type = SCC_AST_STMT_EXPR;
|
||||
|
||||
if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
|
||||
stmt->expr.expr = null;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
stmt->expr.expr = scc_parse_expression(parser);
|
||||
if (stmt->expr.expr == null) {
|
||||
// TODO
|
||||
scc_free(stmt);
|
||||
return null;
|
||||
}
|
||||
|
||||
scc_ast_expr_t *expr = scc_parse_expression(parser);
|
||||
if (expr == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
scc_ast_stmt_t *stmt = ast_stmt_alloc();
|
||||
scc_ast_stmt_expr_init(stmt, expr);
|
||||
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
|
||||
LOG_ERROR("Expected semicolon after expression.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user