feat: 枚举关联数据 ADT — enum Option { Some(i64), None }
This commit is contained in:
+6
-2
@@ -200,19 +200,23 @@ AstNode* ast_make_type_alias(void* alloc, const char* name, TypeKind aliased,
|
||||
// === 枚举相关工厂函数 ===
|
||||
|
||||
AstNode* ast_make_enum_decl(void* alloc, const char* name, const char** variants,
|
||||
size_t count, SourceLoc loc) {
|
||||
TypeKind* payload_types, const char** payload_struct_names,
|
||||
size_t count, SourceLoc loc) {
|
||||
NEW(alloc, AST_ENUM_DECL);
|
||||
n->as.enum_decl.name = name;
|
||||
n->as.enum_decl.variants = variants;
|
||||
n->as.enum_decl.variant_payload_types = payload_types;
|
||||
n->as.enum_decl.variant_payload_struct_names = payload_struct_names;
|
||||
n->as.enum_decl.variant_count = count;
|
||||
return n;
|
||||
}
|
||||
|
||||
AstNode* ast_make_enum_variant(void* alloc, const char* enum_name,
|
||||
const char* variant_name, SourceLoc loc) {
|
||||
const char* variant_name, AstNode* payload, SourceLoc loc) {
|
||||
NEW(alloc, AST_ENUM_VARIANT);
|
||||
n->as.enum_variant.enum_name = enum_name;
|
||||
n->as.enum_variant.variant_name = variant_name;
|
||||
n->as.enum_variant.payload = payload;
|
||||
n->as.enum_variant.variant_index = -1;
|
||||
return n;
|
||||
}
|
||||
|
||||
+12
-4
@@ -104,9 +104,14 @@ struct AstNode {
|
||||
// AST_TYPE_ALIAS
|
||||
struct { const char* name; TypeKind aliased_type; const char* aliased_struct_name; } type_alias;
|
||||
// AST_ENUM_DECL
|
||||
struct { const char* name; const char** variants; size_t variant_count; } enum_decl;
|
||||
struct { const char* name; const char** variants;
|
||||
TypeKind* variant_payload_types; // 每个变体的 payload 类型(TYPE_VOID=无)
|
||||
const char** variant_payload_struct_names; // payload 为 struct 时的类型名
|
||||
size_t variant_count; } enum_decl;
|
||||
// AST_ENUM_VARIANT
|
||||
struct { const char* enum_name; const char* variant_name; int variant_index; } enum_variant;
|
||||
struct { const char* enum_name; const char* variant_name;
|
||||
AstNode* payload; // payload 表达式 (NULL=无 payload)
|
||||
int variant_index; } enum_variant;
|
||||
// AST_INDEX_EXPR
|
||||
struct { struct AstNode* array; struct AstNode* index; } index_expr;
|
||||
// AST_ARRAY_ASSIGN_STMT
|
||||
@@ -150,8 +155,11 @@ AstNode* ast_make_struct_init(void* alloc, const char* type_name, const char** f
|
||||
AstNode* ast_make_field_access(void* alloc, AstNode* object, const char* field, SourceLoc loc);
|
||||
AstNode* ast_make_type_alias(void* alloc, const char* name, TypeKind aliased,
|
||||
const char* aliased_struct, SourceLoc loc);
|
||||
AstNode* ast_make_enum_decl(void* alloc, const char* name, const char** variants, size_t count, SourceLoc loc);
|
||||
AstNode* ast_make_enum_variant(void* alloc, const char* enum_name, const char* variant_name, SourceLoc loc);
|
||||
AstNode* ast_make_enum_decl(void* alloc, const char* name, const char** variants,
|
||||
TypeKind* payload_types, const char** payload_struct_names,
|
||||
size_t count, SourceLoc loc);
|
||||
AstNode* ast_make_enum_variant(void* alloc, const char* enum_name, const char* variant_name,
|
||||
AstNode* payload, SourceLoc loc);
|
||||
AstNode* ast_make_index_expr(void* alloc, AstNode* array, AstNode* index, SourceLoc loc);
|
||||
AstNode* ast_make_array_assign(void* alloc, const char* name, AstNode* index, AstNode* value, SourceLoc loc);
|
||||
AstNode* ast_make_impl_block(void* alloc, const char* struct_name, AstNode** methods, size_t count, SourceLoc loc);
|
||||
|
||||
+58
-18
@@ -67,7 +67,12 @@ static LLVMTypeRef to_llvm_type(CgCtx* ctx, TypeKind kind) {
|
||||
case TYPE_CHAR: return LLVMInt8TypeInContext(ctx->context);
|
||||
case TYPE_STR: return LLVMPointerType(LLVMInt8TypeInContext(ctx->context), 0);
|
||||
case TYPE_STRUCT:
|
||||
case TYPE_ENUM: return LLVMInt64TypeInContext(ctx->context);
|
||||
case TYPE_ENUM: {
|
||||
// tagged union: { i64 tag, i64 payload }
|
||||
LLVMTypeRef fields[] = { LLVMInt64TypeInContext(ctx->context),
|
||||
LLVMInt64TypeInContext(ctx->context) };
|
||||
return LLVMStructTypeInContext(ctx->context, fields, 2, false);
|
||||
}
|
||||
case TYPE_UNKNOWN:
|
||||
case TYPE_ERROR:
|
||||
default: return LLVMVoidTypeInContext(ctx->context);
|
||||
@@ -159,8 +164,11 @@ static LLVMTypeRef type_info_to_llvm(CgCtx* ctx, const TypeInfo* ti) {
|
||||
if (st) return st;
|
||||
}
|
||||
return LLVMVoidTypeInContext(ctx->context);
|
||||
case TYPE_ENUM:
|
||||
return LLVMInt64TypeInContext(ctx->context);
|
||||
case TYPE_ENUM: {
|
||||
LLVMTypeRef f[] = { LLVMInt64TypeInContext(ctx->context),
|
||||
LLVMInt64TypeInContext(ctx->context) };
|
||||
return LLVMStructTypeInContext(ctx->context, f, 2, false);
|
||||
}
|
||||
default:
|
||||
return to_llvm_type(ctx, ti->kind);
|
||||
}
|
||||
@@ -258,23 +266,36 @@ static LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node) {
|
||||
case OP_MOD:
|
||||
return LLVMBuildSRem(ctx->builder, l, r, "srem");
|
||||
case OP_EQ:
|
||||
return is_float ? LLVMBuildFCmp(ctx->builder, LLVMRealOEQ, l, r, "feq")
|
||||
: LLVMBuildICmp(ctx->builder, LLVMIntEQ, l, r, "ieq");
|
||||
case OP_NE:
|
||||
return is_float ? LLVMBuildFCmp(ctx->builder, LLVMRealONE, l, r, "fne")
|
||||
: LLVMBuildICmp(ctx->builder, LLVMIntNE, l, r, "ine");
|
||||
case OP_LT:
|
||||
return is_float ? LLVMBuildFCmp(ctx->builder, LLVMRealOLT, l, r, "flt")
|
||||
: LLVMBuildICmp(ctx->builder, LLVMIntSLT, l, r, "ilt");
|
||||
case OP_GT:
|
||||
return is_float ? LLVMBuildFCmp(ctx->builder, LLVMRealOGT, l, r, "fgt")
|
||||
: LLVMBuildICmp(ctx->builder, LLVMIntSGT, l, r, "igt");
|
||||
case OP_LE:
|
||||
return is_float ? LLVMBuildFCmp(ctx->builder, LLVMRealOLE, l, r, "fle")
|
||||
: LLVMBuildICmp(ctx->builder, LLVMIntSLE, l, r, "ile");
|
||||
case OP_GE:
|
||||
return is_float ? LLVMBuildFCmp(ctx->builder, LLVMRealOGE, l, r, "fge")
|
||||
: LLVMBuildICmp(ctx->builder, LLVMIntSGE, l, r, "ige");
|
||||
case OP_GE: {
|
||||
// 枚举比较: 提取 tag 字段再比较
|
||||
LLVMValueRef cl = l, cr = r;
|
||||
if (node->as.binary.left->type.kind == TYPE_ENUM) {
|
||||
cl = LLVMBuildExtractValue(ctx->builder, l, 0, "enum_tag_l");
|
||||
}
|
||||
if (node->as.binary.right->type.kind == TYPE_ENUM) {
|
||||
cr = LLVMBuildExtractValue(ctx->builder, r, 0, "enum_tag_r");
|
||||
}
|
||||
LLVMIntPredicate pred;
|
||||
switch (node->as.binary.op) {
|
||||
case OP_EQ: pred = LLVMIntEQ; break;
|
||||
case OP_NE: pred = LLVMIntNE; break;
|
||||
case OP_LT: pred = LLVMIntSLT; break;
|
||||
case OP_GT: pred = LLVMIntSGT; break;
|
||||
case OP_LE: pred = LLVMIntSLE; break;
|
||||
case OP_GE: pred = LLVMIntSGE; break;
|
||||
default: return NULL;
|
||||
}
|
||||
if (is_float)
|
||||
return LLVMBuildFCmp(ctx->builder, pred == LLVMIntEQ ? LLVMRealOEQ :
|
||||
pred == LLVMIntNE ? LLVMRealONE : pred == LLVMIntSLT ? LLVMRealOLT :
|
||||
pred == LLVMIntSGT ? LLVMRealOGT : pred == LLVMIntSLE ? LLVMRealOLE :
|
||||
LLVMRealOGE, cl, cr, "fcmp");
|
||||
return LLVMBuildICmp(ctx->builder, pred, cl, cr, "icmp");
|
||||
}
|
||||
case OP_AND:
|
||||
return LLVMBuildAnd(ctx->builder, l, r, "and");
|
||||
case OP_OR:
|
||||
@@ -289,6 +310,9 @@ static LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node) {
|
||||
if (strcmp(node->as.call.name, "print_i64") == 0) {
|
||||
LLVMValueRef arg = codegen_expr(ctx, node->as.call.args[0]);
|
||||
if (!arg) return NULL;
|
||||
// 枚举类型: 提取 tag 字段
|
||||
if (node->as.call.args[0]->type.kind == TYPE_ENUM)
|
||||
arg = LLVMBuildExtractValue(ctx->builder, arg, 0, "tag");
|
||||
LLVMTypeRef i64_ty = LLVMInt64TypeInContext(ctx->context);
|
||||
arg = coerce_int(ctx, arg, LLVMTypeOf(arg), i64_ty);
|
||||
LLVMValueRef fmt = LLVMBuildGlobalStringPtr(ctx->builder, "%lld\n", "fmt_i64");
|
||||
@@ -384,9 +408,25 @@ static LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node) {
|
||||
return LLVMBuildLoad2(ctx->builder, struct_ty, alloca, "struct_val");
|
||||
}
|
||||
|
||||
case AST_ENUM_VARIANT:
|
||||
return LLVMConstInt(LLVMInt64TypeInContext(ctx->context),
|
||||
case AST_ENUM_VARIANT: {
|
||||
// tagged union: { tag, payload }
|
||||
LLVMValueRef tag = LLVMConstInt(LLVMInt64TypeInContext(ctx->context),
|
||||
(unsigned long long)node->as.enum_variant.variant_index, true);
|
||||
LLVMValueRef payload = LLVMConstInt(LLVMInt64TypeInContext(ctx->context), 0, true);
|
||||
if (node->as.enum_variant.payload) {
|
||||
LLVMValueRef pv = codegen_expr(ctx, node->as.enum_variant.payload);
|
||||
if (pv) {
|
||||
// 将 payload 强制转换为 i64
|
||||
LLVMTypeRef pv_ty = LLVMTypeOf(pv);
|
||||
LLVMTypeRef i64_ty = LLVMInt64TypeInContext(ctx->context);
|
||||
if (pv_ty != i64_ty && LLVMGetTypeKind(pv_ty) == LLVMIntegerTypeKind)
|
||||
pv = coerce_int(ctx, pv, pv_ty, i64_ty);
|
||||
payload = pv;
|
||||
}
|
||||
}
|
||||
LLVMValueRef fields[] = { tag, payload };
|
||||
return LLVMConstStruct(fields, 2, false);
|
||||
}
|
||||
|
||||
case AST_METHOD_CALL: {
|
||||
const char* struct_name = node->as.method_call.receiver->type.struct_name;
|
||||
|
||||
+32
-5
@@ -187,15 +187,21 @@ static AstNode* parse_struct_init(Parser* p, const Token* name, ErrorInfo* error
|
||||
static AstNode* parse_ident_or_call(Parser* p, ErrorInfo* error) {
|
||||
const Token* name = advance(p);
|
||||
|
||||
// 枚举变体引用: Name::Variant
|
||||
// 枚举变体引用: Name::Variant 或 Name::Variant(payload)
|
||||
if (peek(p)->kind == TOK_COLON_COLON) {
|
||||
advance(p); // 跳过 ::
|
||||
const Token* variant = expect(p, TOK_IDENT, error, "枚举变体名");
|
||||
if (!variant) return NULL;
|
||||
AstNode* payload = NULL;
|
||||
if (match(p, TOK_LPAREN)) {
|
||||
payload = parse_expr(p, error);
|
||||
if (!payload) return NULL;
|
||||
if (!expect(p, TOK_RPAREN, error, "缺少 ')'")) return NULL;
|
||||
}
|
||||
return ast_make_enum_variant(p->arena,
|
||||
arena_strdup_impl(p->arena, name->start, name->length),
|
||||
arena_strdup_impl(p->arena, variant->start, variant->length),
|
||||
tok_loc(name));
|
||||
payload, tok_loc(name));
|
||||
}
|
||||
|
||||
// 结构体初始化: Name { field: val, ... }
|
||||
@@ -898,18 +904,39 @@ AstNode* parse(Arena* a, const Token* tokens, size_t count,
|
||||
const Token* name = expect(&p, TOK_IDENT, error, "enum 后应为枚举名");
|
||||
if (!name) return NULL;
|
||||
if (!expect(&p, TOK_LBRACE, error, "缺少 '{'")) return NULL;
|
||||
const char* variants[64]; int vcount = 0;
|
||||
const char* variants[64];
|
||||
TypeKind payload_types[64];
|
||||
const char* payload_snames[64];
|
||||
int vcount = 0;
|
||||
while (peek(&p)->kind != TOK_RBRACE && !error->message) {
|
||||
if (vcount >= 64) { error->message = "枚举变体过多(最多64)"; error->filename = p.filename; error->line = peek(&p)->line; error->col = peek(&p)->col; return NULL; }
|
||||
const Token* vname = expect(&p, TOK_IDENT, error, "变体名");
|
||||
if (!vname) return NULL;
|
||||
variants[vcount++] = arena_strdup_impl(p.arena, vname->start, vname->length);
|
||||
variants[vcount] = arena_strdup_impl(p.arena, vname->start, vname->length);
|
||||
payload_types[vcount] = TYPE_VOID;
|
||||
payload_snames[vcount] = NULL;
|
||||
// 可选 payload: Variant(Type)
|
||||
if (peek(&p)->kind == TOK_LPAREN) {
|
||||
advance(&p);
|
||||
TypeInfo pti = parse_type_expr(&p, error);
|
||||
if (pti.kind == TYPE_ERROR) return NULL;
|
||||
payload_types[vcount] = pti.kind;
|
||||
payload_snames[vcount] = pti.struct_name;
|
||||
if (!expect(&p, TOK_RPAREN, error, "缺少 ')'")) return NULL;
|
||||
}
|
||||
vcount++;
|
||||
if (peek(&p)->kind == TOK_COMMA) advance(&p); else break;
|
||||
}
|
||||
if (!expect(&p, TOK_RBRACE, error, "缺少 '}'")) return NULL;
|
||||
const char** v_arr = arena_alloc_impl(p.arena, vcount * sizeof(const char*));
|
||||
memcpy(v_arr, variants, vcount * sizeof(const char*));
|
||||
AstNode* enum_decl = ast_make_enum_decl(p.arena, arena_strdup_impl(p.arena, name->start, name->length), v_arr, vcount, tok_loc(name));
|
||||
TypeKind* pt_arr = arena_alloc_impl(p.arena, vcount * sizeof(TypeKind));
|
||||
memcpy(pt_arr, payload_types, vcount * sizeof(TypeKind));
|
||||
const char** ps_arr = arena_alloc_impl(p.arena, vcount * sizeof(const char*));
|
||||
memcpy(ps_arr, payload_snames, vcount * sizeof(const char*));
|
||||
AstNode* enum_decl = ast_make_enum_decl(p.arena,
|
||||
arena_strdup_impl(p.arena, name->start, name->length),
|
||||
v_arr, pt_arr, ps_arr, vcount, tok_loc(name));
|
||||
if (enum_count >= 64) { error->message = "枚举过多 (最多64)"; error->filename = p.filename; error->line = peek(&p)->line; error->col = peek(&p)->col; return NULL; }
|
||||
enums[enum_count++] = enum_decl;
|
||||
} else if (peek(&p)->kind == TOK_EXTEND) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
enum Option { Some(i64), None }
|
||||
|
||||
fn main() -> i64 {
|
||||
let s = Option::Some(42);
|
||||
let n = Option::None;
|
||||
|
||||
// 打印 tag 值 (Some=0, None=1)
|
||||
print_i64(s);
|
||||
print_i64(n);
|
||||
|
||||
// match 判断是 Some 还是 None(只比较 tag)
|
||||
match s {
|
||||
Option::None => { print_i64(999); }
|
||||
_ => { print_i64(100); }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
+6
-6
@@ -243,11 +243,11 @@ void test_codegen_enum() {
|
||||
/* 构造 AST: enum Color { Red, Green, Blue }
|
||||
fn main() -> i64 { let c = Color::Green; print_i64(c); return 0; } */
|
||||
const char* cvariants[] = {"Red", "Green", "Blue"};
|
||||
AstNode* enum_decl = ast_make_enum_decl(&a, "Color", cvariants, 3, loc_at(1, 1));
|
||||
AstNode* enum_decl = ast_make_enum_decl(&a, "Color", cvariants, NULL, NULL, 3, loc_at(1, 1));
|
||||
AstNode* enums[] = { enum_decl };
|
||||
|
||||
/* let c = Color::Green; */
|
||||
AstNode* cv = ast_make_enum_variant(&a, "Color", "Green", loc_at(1, 1));
|
||||
AstNode* cv = ast_make_enum_variant(&a, "Color", "Green", NULL, loc_at(1, 1));
|
||||
cv->as.enum_variant.variant_index = 1; /* Green = index 1 */
|
||||
cv->type.kind = TYPE_ENUM;
|
||||
|
||||
@@ -426,7 +426,7 @@ void test_codegen_match() {
|
||||
|
||||
/* enum Color { Red, Green, Blue } */
|
||||
const char* variants[] = {"Red", "Green", "Blue"};
|
||||
AstNode* enum_decl = ast_make_enum_decl(&a, "Color", variants, 3, loc_at(1, 1));
|
||||
AstNode* enum_decl = ast_make_enum_decl(&a, "Color", variants, NULL, NULL, 3, loc_at(1, 1));
|
||||
AstNode* enums[] = { enum_decl };
|
||||
|
||||
/* fn main() -> i64 {
|
||||
@@ -445,7 +445,7 @@ void test_codegen_match() {
|
||||
else { return 0; }
|
||||
}
|
||||
*/
|
||||
AstNode* match_val = ast_make_enum_variant(&a, "Color", "Green", loc_at(1, 1));
|
||||
AstNode* match_val = ast_make_enum_variant(&a, "Color", "Green", NULL, loc_at(1, 1));
|
||||
match_val->type.kind = TYPE_ENUM;
|
||||
|
||||
AstNode* let_stmt = ast_make_let(&a, "__match_val", TYPE_UNKNOWN, false, false,
|
||||
@@ -456,7 +456,7 @@ void test_codegen_match() {
|
||||
match_ident->type.kind = TYPE_ENUM;
|
||||
|
||||
// if __match_val == Color::Red { return 1; }
|
||||
AstNode* red_variant = ast_make_enum_variant(&a, "Color", "Red", loc_at(1, 1));
|
||||
AstNode* red_variant = ast_make_enum_variant(&a, "Color", "Red", NULL, loc_at(1, 1));
|
||||
red_variant->type.kind = TYPE_ENUM;
|
||||
AstNode* red_cond = ast_make_binary(&a, OP_EQ, match_ident, red_variant, loc_at(1, 1));
|
||||
red_cond->type.kind = TYPE_BOOL;
|
||||
@@ -467,7 +467,7 @@ void test_codegen_match() {
|
||||
// if __match_val == Color::Green { return 2; }
|
||||
AstNode* match_ident2 = ast_make_ident(&a, "__match_val", loc_at(1, 1));
|
||||
match_ident2->type.kind = TYPE_ENUM;
|
||||
AstNode* green_variant = ast_make_enum_variant(&a, "Color", "Green", loc_at(1, 1));
|
||||
AstNode* green_variant = ast_make_enum_variant(&a, "Color", "Green", NULL, loc_at(1, 1));
|
||||
green_variant->type.kind = TYPE_ENUM;
|
||||
AstNode* green_cond = ast_make_binary(&a, OP_EQ, match_ident2, green_variant, loc_at(1, 1));
|
||||
green_cond->type.kind = TYPE_BOOL;
|
||||
|
||||
Reference in New Issue
Block a user