feat(ast): 添加内置类型定义和AST节点初始化函数
添加了完整的内置类型支持,包括整数、浮点数、字符、布尔等基本类型, 以及它们的有符号/无符号变体。同时添加了大量的AST节点初始化函数, 简化了AST节点的创建过程。 BREAKING CHANGE: 重构了AST表达式和声明结构,移除了冗余字段, 统一了命名规范,并修改了函数调用和成员访问的表示方式。
This commit is contained in:
@@ -188,7 +188,6 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
|
||||
}
|
||||
|
||||
scc_ast_decl_t *decl = scc_malloc(sizeof(scc_ast_decl_t));
|
||||
|
||||
/*
|
||||
(6.7.5) declarator:
|
||||
pointeropt direct-declarator
|
||||
@@ -203,18 +202,14 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
|
||||
direct-declarator ( identifier-listopt )
|
||||
*/
|
||||
if (!scc_parser_consume_if(parser, SCC_TOK_L_PAREN)) {
|
||||
// TODO
|
||||
if (scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) {
|
||||
decl->base.type = SCC_AST_DECL_VAR;
|
||||
decl->var.type = type;
|
||||
decl->var.name = scc_cstring_as_cstr(&tok.lexeme);
|
||||
decl->var.init = null;
|
||||
scc_ast_decl_val_init(decl, type, scc_cstring_as_cstr(&tok.lexeme),
|
||||
null);
|
||||
goto RETURN;
|
||||
} else if (scc_parser_consume_if(parser, SCC_TOK_ASSIGN)) {
|
||||
decl->base.type = SCC_AST_DECL_VAR;
|
||||
decl->var.type = type;
|
||||
decl->var.name = scc_cstring_as_cstr(&tok.lexeme);
|
||||
decl->var.init = scc_parse_expression(parser);
|
||||
scc_ast_expr_t *init = scc_parse_expression(parser);
|
||||
scc_ast_decl_val_init(decl, type, scc_cstring_as_cstr(&tok.lexeme),
|
||||
init);
|
||||
goto RETURN;
|
||||
}
|
||||
// TODO
|
||||
@@ -223,13 +218,11 @@ scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) {
|
||||
|
||||
// function decl
|
||||
decl->base.type = SCC_AST_DECL_FUNC;
|
||||
decl->func.name = scc_cstring_as_cstr(&tok.lexeme);
|
||||
decl->name = scc_cstring_as_cstr(&tok.lexeme);
|
||||
decl->func.type = scc_malloc(sizeof(scc_ast_type_t));
|
||||
decl->func.type->base.type = SCC_AST_TYPE_FUNCTION;
|
||||
scc_vec_init(decl->func.type->function.param_types);
|
||||
decl->func.type->function.return_type = type;
|
||||
// TODO
|
||||
decl->func.type->function.is_variadic = false;
|
||||
|
||||
// TODO param type
|
||||
scc_parser_consume_if(parser, SCC_TOK_VOID);
|
||||
|
||||
@@ -760,7 +760,7 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
|
||||
scc_lexer_tok_drop(&lp);
|
||||
|
||||
scc_ast_expr_t *call = expr_create(parser, SCC_AST_EXPR_CALL);
|
||||
call->call.callee = left;
|
||||
call->call._target = left;
|
||||
scc_vec_init(call->call.args);
|
||||
|
||||
// 解析参数列表
|
||||
@@ -811,13 +811,9 @@ static scc_ast_expr_t *parse_postfix_expression(scc_parser_t *parser) {
|
||||
scc_ast_expr_t *member = expr_create(
|
||||
parser, op_tok.type == SCC_TOK_DOT ? SCC_AST_EXPR_MEMBER
|
||||
: SCC_AST_EXPR_PTR_MEMBER);
|
||||
if (op_tok.type == SCC_TOK_DOT) {
|
||||
member->member.base = left;
|
||||
member->member.member_name = name;
|
||||
} else {
|
||||
member->ptr_member.base = left;
|
||||
member->ptr_member.member_name = name;
|
||||
}
|
||||
member->member.base = left;
|
||||
member->member.name = name;
|
||||
|
||||
scc_lexer_tok_drop(&op_tok);
|
||||
left = member;
|
||||
break;
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
|
||||
@@ -234,7 +234,11 @@ cbool scc_parse_is_storage_class_start(scc_parser_t *parser) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
scc_ast_type_t *scc_parse_type(scc_parser_t *parser) {
|
||||
if (!scc_parse_is_decl_specifier_start(parser)) {
|
||||
return null;
|
||||
}
|
||||
const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser);
|
||||
scc_ast_type_t *ret = null;
|
||||
if (tok_ptr->type == SCC_TOK_INT) {
|
||||
|
||||
Reference in New Issue
Block a user