diff --git a/src/sema/mono.c b/src/sema/mono.c new file mode 100644 index 0000000..10ad746 --- /dev/null +++ b/src/sema/mono.c @@ -0,0 +1,97 @@ +#include "sema_internal.h" + +// 将 AST 中所有匹配 type_param_name 的类型引用替换为 concrete_type +void subst_ast_types(AstNode* node, const char* tparam, TypeKind concrete, const char* concrete_sname); + +void subst_type_info(TypeInfo* ti, const char* tparam, TypeKind concrete, const char* concrete_sname) { + if (ti->kind == TYPE_STRUCT && ti->struct_name && strcmp(ti->struct_name, tparam) == 0) { + ti->kind = concrete; + ti->struct_name = concrete_sname; + } +} + +void subst_ast_types(AstNode* node, const char* tparam, TypeKind concrete, const char* concrete_sname) { + if (!node) return; + // 替换节点自身类型 + subst_type_info(&node->type, tparam, concrete, concrete_sname); + switch (node->kind) { + case AST_PROGRAM: + for (size_t i = 0; i < node->as.program.fn_count; i++) + subst_ast_types(node->as.program.functions[i], tparam, concrete, concrete_sname); + break; + case AST_FUNCTION: + if (node->as.function.return_type == TYPE_STRUCT + && node->as.function.return_struct_type_name + && strcmp(node->as.function.return_struct_type_name, tparam) == 0) { + node->as.function.return_type = concrete; + node->as.function.return_struct_type_name = concrete_sname; + } + for (size_t i = 0; i < node->as.function.param_count; i++) + subst_ast_types(node->as.function.params[i], tparam, concrete, concrete_sname); + subst_ast_types(node->as.function.body, tparam, concrete, concrete_sname); + break; + case AST_PARAMETER: + if (node->as.parameter.type == TYPE_STRUCT && node->as.parameter.struct_type_name + && strcmp(node->as.parameter.struct_type_name, tparam) == 0) { + node->as.parameter.type = concrete; + node->as.parameter.struct_type_name = concrete_sname; + } + break; + case AST_BLOCK: + for (size_t i = 0; i < node->as.block.stmt_count; i++) + subst_ast_types(node->as.block.stmts[i], tparam, concrete, concrete_sname); + break; + case AST_LET_STMT: + if (node->as.let_stmt.annot_type == TYPE_STRUCT && node->as.let_stmt.struct_type_name + && strcmp(node->as.let_stmt.struct_type_name, tparam) == 0) { + node->as.let_stmt.annot_type = concrete; + node->as.let_stmt.struct_type_name = concrete_sname; + } + subst_ast_types(node->as.let_stmt.init, tparam, concrete, concrete_sname); + break; + case AST_IF_STMT: + subst_ast_types(node->as.if_stmt.cond, tparam, concrete, concrete_sname); + subst_ast_types(node->as.if_stmt.then_block, tparam, concrete, concrete_sname); + subst_ast_types(node->as.if_stmt.else_block, tparam, concrete, concrete_sname); + break; + case AST_WHILE_STMT: + subst_ast_types(node->as.while_stmt.cond, tparam, concrete, concrete_sname); + subst_ast_types(node->as.while_stmt.body, tparam, concrete, concrete_sname); + break; + case AST_RETURN_STMT: + subst_ast_types(node->as.return_stmt.expr, tparam, concrete, concrete_sname); + break; + case AST_EXPR_STMT: + subst_ast_types(node->as.expr_stmt.expr, tparam, concrete, concrete_sname); + break; + case AST_BINARY_EXPR: + subst_ast_types(node->as.binary.left, tparam, concrete, concrete_sname); + subst_ast_types(node->as.binary.right, tparam, concrete, concrete_sname); + break; + case AST_UNARY_EXPR: + subst_ast_types(node->as.unary.operand, tparam, concrete, concrete_sname); + break; + case AST_CALL_EXPR: + for (size_t i = 0; i < node->as.call.arg_count; i++) + subst_ast_types(node->as.call.args[i], tparam, concrete, concrete_sname); + break; + case AST_ASSIGN_STMT: + subst_ast_types(node->as.assign_stmt.value, tparam, concrete, concrete_sname); + break; + case AST_FIELD_ACCESS: + subst_ast_types(node->as.field_access.object, tparam, concrete, concrete_sname); + break; + case AST_STRUCT_INIT: + for (size_t i = 0; i < node->as.struct_init.field_count; i++) + subst_ast_types(node->as.struct_init.field_values[i], tparam, concrete, concrete_sname); + break; + default: break; + } +} + +// 单态化全局状态 +// 单态化队列: 泛型函数调用时生成的具象化函数 +AstNode* mono_queue[256]; +size_t mono_count = 0; +Arena* mono_arena = NULL; +AstNode* g_program = NULL; // 当前 AST_PROGRAM(用于查找泛型函数模板) diff --git a/src/sema/typeck.c b/src/sema/typeck.c index e456f68..34078f4 100644 --- a/src/sema/typeck.c +++ b/src/sema/typeck.c @@ -1,104 +1,11 @@ #include "sema_internal.h" // === 泛型单态化: AST 类型替换 === -// 将 AST 中所有匹配 type_param_name 的类型引用替换为 concrete_type -void subst_ast_types(AstNode* node, const char* tparam, TypeKind concrete, const char* concrete_sname); - -void subst_type_info(TypeInfo* ti, const char* tparam, TypeKind concrete, const char* concrete_sname) { - if (ti->kind == TYPE_STRUCT && ti->struct_name && strcmp(ti->struct_name, tparam) == 0) { - ti->kind = concrete; - ti->struct_name = concrete_sname; - } -} - -void subst_ast_types(AstNode* node, const char* tparam, TypeKind concrete, const char* concrete_sname) { - if (!node) return; - // 替换节点自身类型 - subst_type_info(&node->type, tparam, concrete, concrete_sname); - switch (node->kind) { - case AST_PROGRAM: - for (size_t i = 0; i < node->as.program.fn_count; i++) - subst_ast_types(node->as.program.functions[i], tparam, concrete, concrete_sname); - break; - case AST_FUNCTION: - if (node->as.function.return_type == TYPE_STRUCT - && node->as.function.return_struct_type_name - && strcmp(node->as.function.return_struct_type_name, tparam) == 0) { - node->as.function.return_type = concrete; - node->as.function.return_struct_type_name = concrete_sname; - } - for (size_t i = 0; i < node->as.function.param_count; i++) - subst_ast_types(node->as.function.params[i], tparam, concrete, concrete_sname); - subst_ast_types(node->as.function.body, tparam, concrete, concrete_sname); - break; - case AST_PARAMETER: - if (node->as.parameter.type == TYPE_STRUCT && node->as.parameter.struct_type_name - && strcmp(node->as.parameter.struct_type_name, tparam) == 0) { - node->as.parameter.type = concrete; - node->as.parameter.struct_type_name = concrete_sname; - } - break; - case AST_BLOCK: - for (size_t i = 0; i < node->as.block.stmt_count; i++) - subst_ast_types(node->as.block.stmts[i], tparam, concrete, concrete_sname); - break; - case AST_LET_STMT: - if (node->as.let_stmt.annot_type == TYPE_STRUCT && node->as.let_stmt.struct_type_name - && strcmp(node->as.let_stmt.struct_type_name, tparam) == 0) { - node->as.let_stmt.annot_type = concrete; - node->as.let_stmt.struct_type_name = concrete_sname; - } - subst_ast_types(node->as.let_stmt.init, tparam, concrete, concrete_sname); - break; - case AST_IF_STMT: - subst_ast_types(node->as.if_stmt.cond, tparam, concrete, concrete_sname); - subst_ast_types(node->as.if_stmt.then_block, tparam, concrete, concrete_sname); - subst_ast_types(node->as.if_stmt.else_block, tparam, concrete, concrete_sname); - break; - case AST_WHILE_STMT: - subst_ast_types(node->as.while_stmt.cond, tparam, concrete, concrete_sname); - subst_ast_types(node->as.while_stmt.body, tparam, concrete, concrete_sname); - break; - case AST_RETURN_STMT: - subst_ast_types(node->as.return_stmt.expr, tparam, concrete, concrete_sname); - break; - case AST_EXPR_STMT: - subst_ast_types(node->as.expr_stmt.expr, tparam, concrete, concrete_sname); - break; - case AST_BINARY_EXPR: - subst_ast_types(node->as.binary.left, tparam, concrete, concrete_sname); - subst_ast_types(node->as.binary.right, tparam, concrete, concrete_sname); - break; - case AST_UNARY_EXPR: - subst_ast_types(node->as.unary.operand, tparam, concrete, concrete_sname); - break; - case AST_CALL_EXPR: - for (size_t i = 0; i < node->as.call.arg_count; i++) - subst_ast_types(node->as.call.args[i], tparam, concrete, concrete_sname); - break; - case AST_ASSIGN_STMT: - subst_ast_types(node->as.assign_stmt.value, tparam, concrete, concrete_sname); - break; - case AST_FIELD_ACCESS: - subst_ast_types(node->as.field_access.object, tparam, concrete, concrete_sname); - break; - case AST_STRUCT_INIT: - for (size_t i = 0; i < node->as.struct_init.field_count; i++) - subst_ast_types(node->as.struct_init.field_values[i], tparam, concrete, concrete_sname); - break; - default: break; - } -} // === 类型关系 === TypeKind current_return_type = TYPE_VOID; const char* current_return_struct_name = NULL; -// 单态化队列: 泛型函数调用时生成的具象化函数 -AstNode* mono_queue[256]; -size_t mono_count = 0; -Arena* mono_arena = NULL; -AstNode* g_program = NULL; // 当前 AST_PROGRAM(用于查找泛型函数模板) // === 类型关系(基于 TypeTable 数据驱动)=== TypeKind promote(TypeKind a, TypeKind b) {