feat: 类型别名 type alias (P1 #10)

- lexer: TOK_TYPE 关键字
- ast: AST_TYPE_ALIAS + AST_PROGRAM aliases数组
- parser: parse_type_expr() 抽取, type Name = Type; 解析
- sema: 别名注册+解析, 类型标注/struct字段/函数参数均支持
- 新增测试: 15_type_alias.l, 16_type_alias_struct.l

测试: 112 通过 (41+15+41+15)
This commit is contained in:
2026-06-05 13:54:58 +08:00
parent da9a7065dd
commit ab88ea2753
13 changed files with 235 additions and 79 deletions
+92 -18
View File
@@ -30,6 +30,10 @@ static void analyze_expr(AstNode* node, Scope* scope, ErrorList* errors, Arena*
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"未定义的变量 '%s'", node->as.ident.name);
node->type.kind = TYPE_ERROR;
} else if (sym->is_type_alias) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"'%s' 是类型别名,不能作为表达式使用", node->as.ident.name);
node->type.kind = TYPE_ERROR;
} else if (sym->kind == SYM_FUNCTION) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"'%s' 是函数,不能作为表达式使用", node->as.ident.name);
@@ -227,7 +231,18 @@ static void analyze_expr(AstNode* node, Scope* scope, ErrorList* errors, Arena*
}
case AST_STRUCT_INIT: {
Symbol* struct_sym = scope_lookup_struct(scope, node->as.struct_init.type_name);
const char* resolved_type_name = node->as.struct_init.type_name;
Symbol* struct_sym = scope_lookup_struct(scope, resolved_type_name);
if (!struct_sym) {
// 检查是否是类型别名指向结构体
Symbol* alias_sym = scope_lookup(scope, resolved_type_name);
if (alias_sym && alias_sym->is_type_alias && alias_sym->struct_type_name) {
resolved_type_name = alias_sym->struct_type_name;
struct_sym = scope_lookup_struct(scope, resolved_type_name);
// 更新 type_name 为真实结构体名(codegen 需要)
node->as.struct_init.type_name = resolved_type_name;
}
}
if (!struct_sym) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"未定义的结构体类型 '%s'", node->as.struct_init.type_name);
@@ -267,7 +282,7 @@ static void analyze_expr(AstNode* node, Scope* scope, ErrorList* errors, Arena*
}
if (node->type.kind != TYPE_ERROR) {
node->type.kind = TYPE_STRUCT;
node->type.struct_name = node->as.struct_init.type_name;
node->type.struct_name = resolved_type_name;
}
break;
}
@@ -281,6 +296,18 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
switch (node->kind) {
case AST_PROGRAM:
// Pass 0: 注册类型别名
for (size_t i = 0; i < node->as.program.alias_count; i++) {
AstNode* alias = node->as.program.type_aliases[i];
Symbol* sym = scope_insert(scope, a, alias->as.type_alias.name,
SYM_VARIABLE, alias->as.type_alias.aliased_type);
if (sym) {
sym->is_type_alias = true;
if (alias->as.type_alias.aliased_struct_name) {
sym->struct_type_name = alias->as.type_alias.aliased_struct_name;
}
}
}
// 第一遍:收集所有结构体定义
for (size_t i = 0; i < node->as.program.struct_count; i++) {
AstNode* sd = node->as.program.structs[i];
@@ -305,12 +332,31 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
TypeKind* pts = (TypeKind*)arena_alloc_impl(a, fn->as.function.param_count * sizeof(TypeKind));
const char** pstruct_names = (const char**)arena_alloc_impl(a, fn->as.function.param_count * sizeof(const char*));
for (size_t j = 0; j < fn->as.function.param_count; j++) {
pts[j] = fn->as.function.params[j]->as.parameter.type;
pstruct_names[j] = fn->as.function.params[j]->as.parameter.struct_type_name;
TypeKind pt = fn->as.function.params[j]->as.parameter.type;
const char* psn = fn->as.function.params[j]->as.parameter.struct_type_name;
// 解析参数类型的别名
if (psn) {
Symbol* as = scope_lookup(scope, psn);
if (as && as->is_type_alias) {
pt = as->type;
psn = as->struct_type_name;
}
}
pts[j] = pt;
pstruct_names[j] = psn;
}
// 解析返回类型的别名
TypeKind ret_t = fn->as.function.return_type;
const char* ret_sn = fn->as.function.return_struct_type_name;
if (ret_sn) {
Symbol* as = scope_lookup(scope, ret_sn);
if (as && as->is_type_alias) {
ret_t = as->type;
ret_sn = as->struct_type_name;
}
}
scope_insert_function(scope, a, fn->as.function.name,
fn->as.function.return_type,
fn->as.function.return_struct_type_name,
ret_t, ret_sn,
pts, pstruct_names,
fn->as.function.param_count);
}
@@ -322,12 +368,33 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
case AST_FUNCTION: {
Scope* fn_scope = scope_new(a, scope);
// 注册参数
// 注册参数(同时解析类型别名,更新 AST 节点供 codegen 使用)
for (size_t i = 0; i < node->as.function.param_count; i++) {
AstNode* p = node->as.function.params[i];
Symbol* sym = scope_insert(fn_scope, a, p->as.parameter.name, SYM_PARAMETER, p->as.parameter.type);
if (sym && p->as.parameter.type == TYPE_STRUCT && p->as.parameter.struct_type_name) {
sym->struct_type_name = p->as.parameter.struct_type_name;
TypeKind pt = p->as.parameter.type;
const char* psn = p->as.parameter.struct_type_name;
if (psn) {
Symbol* as = scope_lookup(scope, psn);
if (as && as->is_type_alias) {
pt = as->type;
psn = as->struct_type_name;
// 更新 AST 节点
p->as.parameter.type = pt;
p->as.parameter.struct_type_name = psn;
}
}
Symbol* sym = scope_insert(fn_scope, a, p->as.parameter.name, SYM_PARAMETER, pt);
if (sym && pt == TYPE_STRUCT && psn) {
sym->struct_type_name = psn;
}
}
// 解析返回类型的别名
const char* ret_sn = node->as.function.return_struct_type_name;
if (ret_sn) {
Symbol* as = scope_lookup(scope, ret_sn);
if (as && as->is_type_alias) {
node->as.function.return_type = as->type;
node->as.function.return_struct_type_name = as->struct_type_name;
}
}
TypeKind saved = current_return_type;
@@ -355,15 +422,22 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
if (node->as.let_stmt.has_type_annot) {
const char* annot_struct = node->as.let_stmt.struct_type_name;
if (annot_struct) {
// struct 类型标注
Symbol* st_sym = scope_lookup_struct(scope, annot_struct);
if (!st_sym) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"未定义的结构体类型 '%s'", annot_struct);
break;
// 先检查是否是类型别名
Symbol* alias_sym = scope_lookup(scope, annot_struct);
if (alias_sym && alias_sym->is_type_alias) {
var_type = alias_sym->type;
var_struct_name = alias_sym->struct_type_name;
} else {
// struct 类型标注
Symbol* st_sym = scope_lookup_struct(scope, annot_struct);
if (!st_sym) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"未定义的类型 '%s'", annot_struct);
break;
}
var_type = TYPE_STRUCT;
var_struct_name = annot_struct;
}
var_type = TYPE_STRUCT;
var_struct_name = annot_struct;
} else {
var_type = node->as.let_stmt.annot_type;
}