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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user