feat: 枚举关联数据 ADT — enum Option { Some(i64), None }
This commit is contained in:
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user