#ifndef CODEGEN_INTERNAL_H #define CODEGEN_INTERNAL_H #include "codegen.h" #include "ast.h" #include "arena.h" #include "l_lang.h" #include "visit.h" #include #include #include #include // 递归深度限制 extern int codegen_depth; #define MAX_CODEGEN_DEPTH 1000 // === 内部状态 === typedef struct VarEntry { const char* name; LLVMValueRef alloca; LLVMTypeRef alloca_type; struct VarEntry* next; } VarEntry; typedef struct FnEntry { const char* name; LLVMValueRef fn; TypeKind ret; TypeKind* params; size_t pc; struct FnEntry* next; } FnEntry; typedef struct StructTypeEntry { const char* name; LLVMTypeRef llvm_type; size_t field_count; struct StructTypeEntry* next; } StructTypeEntry; typedef struct { Arena* arena; LLVMContextRef context; LLVMModuleRef module; LLVMBuilderRef builder; VarEntry* var_table; const char* error; FnEntry* fn_table; StructTypeEntry* struct_table; LLVMValueRef printf_fn; LLVMTypeRef printf_ty; LLVMValueRef malloc_fn; LLVMValueRef free_fn; LLVMValueRef strlen_fn; LLVMValueRef memcpy_fn; LLVMValueRef* cleanup_list; size_t cleanup_count; size_t cleanup_cap; AstNode* defer_exprs[64]; size_t defer_count; } CgCtx; // === 类型映射 === LLVMTypeRef to_llvm_type(CgCtx* ctx, TypeKind kind); LLVMValueRef to_llvm_const(LLVMTypeRef ty, AstNode* lit); LLVMTypeRef type_info_to_llvm(CgCtx* ctx, const TypeInfo* ti); LLVMValueRef coerce_int(CgCtx* ctx, LLVMValueRef val, LLVMTypeRef from_ty, LLVMTypeRef to_ty); // === 表操作 === LLVMValueRef find_var(CgCtx* ctx, const char* name); void add_var(CgCtx* ctx, const char* name, LLVMValueRef alloca, LLVMTypeRef alloca_type); LLVMValueRef find_fn(CgCtx* ctx, const char* name); void add_fn(CgCtx* ctx, const char* name, LLVMValueRef fn); void add_struct_type(CgCtx* ctx, const char* name, LLVMTypeRef ty, size_t fc); LLVMTypeRef find_struct_type(CgCtx* ctx, const char* name); // === 内存清理 === void cleanup_add(CgCtx* ctx, LLVMValueRef alloca); void cleanup_emit(CgCtx* ctx, size_t from_mark); // === 代码生成函数 === void codegen_expr_init(void); LLVMValueRef codegen_expr(CgCtx* ctx, AstNode* node); void codegen_stmt(CgCtx* ctx, AstNode* node); #endif