feat: struct方法 impl (P1 #9)

- lexer: TOK_IMPL 关键字
- ast: AST_IMPL_BLOCK, AST_METHOD_CALL + AST_PROGRAM impls数组
- parser: impl StructName { fn ... } + p.method() 方法调用
- sema: 方法名mangle(StructName$method), self参数, 类型检查
- codegen: METHOD_CALL→mangled函数调用(recv为第一参数)
- 新增集成测试: 19_struct_method.l

P1 4项全部完成: type alias + enum + array + impl
测试: 145 通过 (41+15+65+24)
This commit is contained in:
2026-06-05 14:30:24 +08:00
parent 2923e7574d
commit 9f6e695ba8
11 changed files with 340 additions and 20 deletions
+22
View File
@@ -368,6 +368,28 @@ static LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node) {
return LLVMConstInt(LLVMInt64TypeInContext(ctx->context),
(unsigned long long)node->as.enum_variant.variant_index, true);
case AST_METHOD_CALL: {
const char* struct_name = node->as.method_call.receiver->type.struct_name;
char mangled[256];
snprintf(mangled, sizeof(mangled), "%s$%s", struct_name,
node->as.method_call.method_name);
LLVMValueRef fn = find_fn(ctx, mangled);
if (!fn) return NULL;
// 参数列表: [receiver, 用户参数...]
LLVMValueRef args[16];
args[0] = codegen_expr(ctx, node->as.method_call.receiver);
if (!args[0]) return NULL;
for (size_t i = 0; i < node->as.method_call.arg_count; i++) {
args[i + 1] = codegen_expr(ctx, node->as.method_call.args[i]);
if (!args[i + 1]) return NULL;
}
LLVMTypeRef fn_ty = LLVMGlobalGetValueType(fn);
LLVMTypeRef ret_ty = LLVMGetReturnType(fn_ty);
return LLVMBuildCall2(ctx->builder, fn_ty, fn, args,
(unsigned)(node->as.method_call.arg_count + 1),
ret_ty == LLVMVoidTypeInContext(ctx->context) ? "" : "method_call");
}
case AST_INDEX_EXPR: {
// 获取数组变量的指针
AstNode* arr_node = node->as.index_expr.array;