feat: 枚举关联数据 ADT — enum Option { Some(i64), None }

This commit is contained in:
2026-06-06 14:21:43 +08:00
parent 0ec3c3d65f
commit 0e1f8c5795
9 changed files with 172 additions and 37 deletions
+26
View File
@@ -346,6 +346,30 @@ static void analyze_enum_variant(AstNode* node, Scope* scope, ErrorList* errors,
node->type.kind = TYPE_ERROR; return;
}
node->as.enum_variant.variant_index = vi;
// ADT: 检查 payload
TypeKind expected_pt = TYPE_VOID;
if (enum_sym->variant_payload_types)
expected_pt = enum_sym->variant_payload_types[vi];
if (node->as.enum_variant.payload) {
if (expected_pt == TYPE_VOID && enum_sym->variant_payload_types) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"枚举变体 '%s::%s' 不接受 payload",
node->as.enum_variant.enum_name, node->as.enum_variant.variant_name);
node->type.kind = TYPE_ERROR; return;
}
analyze_expr(node->as.enum_variant.payload, scope, errors, a);
TypeKind actual = node->as.enum_variant.payload->type.kind;
if (actual != TYPE_ERROR && actual != expected_pt) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"枚举变体 payload 类型不匹配: 期望 '%s',得到 '%s'",
type_name(expected_pt), type_name(actual));
}
} else if (expected_pt != TYPE_VOID) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"枚举变体 '%s::%s' 需要 payload 类型 '%s'",
node->as.enum_variant.enum_name, node->as.enum_variant.variant_name,
type_name(expected_pt));
}
node->type.kind = TYPE_ENUM;
}
@@ -451,6 +475,8 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
AstNode* ed = node->as.program.enums[i];
scope_insert_enum(scope, a, ed->as.enum_decl.name,
ed->as.enum_decl.variants,
ed->as.enum_decl.variant_payload_types,
ed->as.enum_decl.variant_payload_struct_names,
ed->as.enum_decl.variant_count);
}
// 第一遍:收集所有结构体定义
+10 -1
View File
@@ -35,6 +35,8 @@ 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->variant_payload_types = NULL;
sym->variant_payload_struct_names = NULL;
sym->array_element_type = 0;
sym->array_element_struct_name = NULL;
sym->array_size = 0;
@@ -66,6 +68,8 @@ 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->variant_payload_types = NULL;
sym->variant_payload_struct_names = NULL;
sym->array_element_type = 0;
sym->array_element_struct_name = NULL;
sym->array_size = 0;
@@ -93,6 +97,8 @@ 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->variant_payload_types = NULL;
sym->variant_payload_struct_names = NULL;
sym->array_element_type = 0;
sym->array_element_struct_name = NULL;
sym->array_size = 0;
@@ -122,7 +128,8 @@ int scope_struct_field_index(const Symbol* sym, const char* field_name) {
}
Symbol* scope_insert_enum(Scope* scope, void* alloc, const char* name,
const char** vnames, size_t vc) {
const char** vnames, TypeKind* ptypes,
const char** pstruct_names, size_t vc) {
if (scope->head) {
for (Symbol* sym = scope->head; sym; sym = sym->next) {
if (strcmp(sym->name, name) == 0) return NULL;
@@ -138,6 +145,8 @@ Symbol* scope_insert_enum(Scope* scope, void* alloc, const char* name,
sym->struct_field_struct_names = NULL;
sym->struct_field_count = vc;
sym->struct_type_name = NULL;
sym->variant_payload_types = ptypes;
sym->variant_payload_struct_names = pstruct_names;
sym->array_element_type = 0;
sym->array_element_struct_name = NULL;
sym->array_size = 0;
+5 -1
View File
@@ -29,6 +29,9 @@ typedef struct Symbol {
TypeKind array_element_type;
const char* array_element_struct_name;
int64_t array_size;
// 枚举特有(ADT payload
TypeKind* variant_payload_types;
const char** variant_payload_struct_names;
// 类型别名标记
bool is_type_alias;
// 链表(同一作用域内的下一个符号)
@@ -69,7 +72,8 @@ int scope_struct_field_index(const Symbol* sym, const char* field_name);
// 插入枚举符号
Symbol* scope_insert_enum(Scope* scope, void* alloc, const char* name,
const char** vnames, size_t vc);
const char** vnames, TypeKind* ptypes,
const char** pstruct_names, size_t vc);
// 在枚举符号中查找变体索引(返回 -1 表示未找到)
int scope_enum_variant_index(const Symbol* sym, const char* variant_name);