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:
+92
-18
@@ -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;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ Symbol* scope_insert(Scope* scope, void* alloc, const char* name,
|
||||
sym->struct_field_types = NULL;
|
||||
sym->struct_field_count = 0;
|
||||
sym->struct_type_name = NULL;
|
||||
sym->is_type_alias = false;
|
||||
sym->next = scope->head;
|
||||
scope->head = sym;
|
||||
return sym;
|
||||
@@ -60,6 +61,7 @@ Symbol* scope_insert_function(Scope* scope, void* alloc, const char* name,
|
||||
sym->struct_field_types = NULL;
|
||||
sym->struct_field_count = 0;
|
||||
sym->struct_type_name = NULL;
|
||||
sym->is_type_alias = false;
|
||||
sym->next = scope->head;
|
||||
scope->head = sym;
|
||||
return sym;
|
||||
@@ -83,6 +85,7 @@ Symbol* scope_insert_struct(Scope* scope, void* alloc, const char* name,
|
||||
sym->struct_field_struct_names = fstruct_names;
|
||||
sym->struct_field_count = fc;
|
||||
sym->struct_type_name = NULL;
|
||||
sym->is_type_alias = false;
|
||||
sym->next = scope->head;
|
||||
scope->head = sym;
|
||||
return sym;
|
||||
|
||||
@@ -24,6 +24,8 @@ typedef struct Symbol {
|
||||
size_t struct_field_count;
|
||||
// 变量引用结构体类型时,记录具体类型名
|
||||
const char* struct_type_name;
|
||||
// 类型别名标记
|
||||
bool is_type_alias;
|
||||
// 链表(同一作用域内的下一个符号)
|
||||
struct Symbol* next;
|
||||
} Symbol;
|
||||
|
||||
Reference in New Issue
Block a user