import t, c from stdint import * import string import viperlib import memhub import hashtable import lib.core.Handles.HandlesTranslator as HT # ============================================================ # TypeKind - 类型种类枚举 # # 替代 TransPyC 中 CType.position frozenset 的元属性系统。 # 每个 TypeInfo 通过 Kind 字段标记其种类,避免 Python ClassVar 反射。 # ============================================================ class TypeKind(t.CEnum): Basic: t.State # 基本类型(int/char/float/double/bool 等) Pointer: t.State # 指针(T*)— 指针层数由 TypeInfo.PtrCount 表达 Struct: t.State # 结构体/类 Union: t.State # 联合体 Enum: t.State # 枚举 Typedef: t.State # 类型别名 Function: t.State # 函数指针 Array: t.State # 数组 T[N] Void: t.State # void # ============================================================ # TypeInfo - 类型信息结构 # # 设计原则(相对 TransPyC CTypeInfo 的简化): # - POD 数据结构,无虚函数,无 Python 元特性(ClassVar/Generic/frozenset) # - 通过 mbuddy 分配,调用方管理生命周期(参考 llvmlite Module 模式) # - 通过 Kind 枚举代替 position frozenset # - PtrCount 表达指针层数(0=非指针, 1=T*, 2=T**) # - IsSigned 三态:-1=不适用(void/float), 0=unsigned, 1=signed # # 字段布局(8 字段): # Kind : i32 类型种类(TypeKind 枚举值) # Name : i8* 类型名(如 'int', 'CInt', 'MyStruct'),可能为 None # Size : i32 位宽(0=void/未知;int=32, char=8, double=64, long long=64) # Align : i32 对齐字节数(0=默认) # IsSigned : i32 -1=N/A, 0=unsigned, 1=signed # PtrCount : i32 指针层数 # IsConst : i32 const 限定符(0/1) # IsVolatile : i32 volatile 限定符(0/1) # # 注意:Size 使用位宽(bit width)而非字节数,与 LLVM IR 的 i{N} 和 # TransPyC CType.Size 约定一致(CInt.Size=32, CChar.Size=8)。 # ============================================================ @t.NoVTable class TypeInfo: Kind: int Name: str Size: int Align: int IsSigned: int PtrCount: int IsConst: int IsVolatile: int # ============================================================ # TypeRegistry - 类型注册表 # # 维护 name(str) → TypeInfo* 映射,基于 HashTable 实现 O(1) 查找。 # 替代 TransPyC CTypeRegistry 的 _name_to_class dict。 # 内置基本类型(int/char/void/...)由 InitBasicTypes 注册。 # ============================================================ class TypeRegistry: _ht: hashtable.HashTable | t.CPtr __mbuddy__: memhub.MemManager | t.CPtr def Register(self, ti: TypeInfo | t.CPtr) -> int: """注册一个 TypeInfo。ti.Name 字段必须已设置。 Returns: 1 表示成功,0 表示失败(ti 为 None 或 Name 为 None) """ if ti is None: return 0 if ti.Name is None: return 0 self._ht[ti.Name] = ti return 1 def Lookup(self, name: str) -> TypeInfo | t.CPtr: """按名称查找 TypeInfo。 Returns: 找到返回 TypeInfo*,找不到返回 None """ if name is None: return None return self._ht[name] def Has(self, name: str) -> int: """检查类型是否已注册。""" if name is None: return 0 return name in self._ht # ============================================================ # NewTypeInfo - 工厂函数:分配并初始化一个 TypeInfo # # 默认值:Kind=Basic, IsSigned=-1, 其余=0/None # ============================================================ def NewTypeInfo(pool: memhub.MemManager | t.CPtr) -> TypeInfo | t.CPtr: ptr: TypeInfo | t.CPtr = pool.alloc(TypeInfo.__sizeof__()) if ptr is None: return None string.memset(ptr, 0, TypeInfo.__sizeof__()) ptr.Kind = TypeKind.Basic ptr.IsSigned = -1 return ptr # ============================================================ # NewTypeRegistry - 工厂函数:创建类型注册表 # ============================================================ def NewTypeRegistry(pool: memhub.MemManager | t.CPtr) -> TypeRegistry | t.CPtr: ptr: TypeRegistry | t.CPtr = pool.alloc(TypeRegistry.__sizeof__()) if ptr is None: return None string.memset(ptr, 0, TypeRegistry.__sizeof__()) ptr.__mbuddy__ = pool ptr._ht = hashtable.HashTable(pool) return ptr # ============================================================ # TypeToLLVM - 将 TypeInfo 转换为 LLVM IR 类型字符串 # # 规则: # - Kind == Void 或 (Size==0 且 IsSigned==-1 且 PtrCount==0) → "void" # - void 有 PtrCount > 0 → "i8" + PtrCount 个 "*" # - IsSigned == -1 且 Size > 0 → 浮点: half/float/double/fp128 # - IsSigned != -1 且 Size > 0 → 整数: i{Size} # - 未知 → "i8*" # # Args: # buf: 输出缓冲区(i8*) # buf_size: 缓冲区容量 # ti: TypeInfo 指针 # # Returns: # 写入的字符数(不含 NUL),失败返回 -1 # ============================================================ def TypeToLLVM(buf: t.CChar | t.CPtr, buf_size: t.CSizeT, ti: TypeInfo | t.CPtr) -> int: if buf is None: return -1 if ti is None: return -1 if buf_size == 0: return -1 # 判定 void is_void: int = 0 if ti.Kind == TypeKind.Void: is_void = 1 elif ti.Size == 0 and ti.IsSigned == -1 and ti.PtrCount == 0: is_void = 1 # 写入 base 类型字符串到 buf base_len: int = 0 if is_void == 1: if ti.PtrCount == 0: # "void" if buf_size < 5: return -1 string.strcpy(buf, "void") base_len = 4 else: # void* → i8*(LLVM 中 void* 表示为 i8*) if buf_size < 4: return -1 string.strcpy(buf, "i8") base_len = 2 elif ti.IsSigned == -1: # 浮点 if ti.Size == 16: if buf_size < 5: return -1 string.strcpy(buf, "half") base_len = 4 elif ti.Size == 32: if buf_size < 6: return -1 string.strcpy(buf, "float") base_len = 5 elif ti.Size == 64: if buf_size < 7: return -1 string.strcpy(buf, "double") base_len = 6 elif ti.Size == 128: if buf_size < 6: return -1 string.strcpy(buf, "fp128") base_len = 5 else: # 未知浮点尺寸 → double 兜底 if buf_size < 7: return -1 string.strcpy(buf, "double") base_len = 6 else: # 整数: i{Size},用 snprintf 安全写入 if ti.Size <= 0: # 无效尺寸 → i8 兜底 if buf_size < 4: return -1 string.strcpy(buf, "i8") base_len = 2 else: viperlib.snprintf(buf, buf_size, "i%d", ti.Size) base_len = string.strlen(buf) # 追加 PtrCount 个 "*" if base_len + ti.PtrCount + 1 > buf_size: return -1 pos: int = base_len for i in range(ti.PtrCount): buf[pos] = '*' pos += 1 buf[pos] = 0 return pos # ============================================================ # Mixin - 所有 Handle 的非多态基类(对应 TransPyC 的 BaseHandle) # # @t.NoVTable 继承:字段展平嵌入子类,无 vtable 开销(对应 C++ 非多态继承)。 # 子类继承 Trans 字段 + 共享工具方法,编译器自动生成子类方法包装 # (self bitcast 为父类指针后调用),子类可直接调用继承的方法。 # # 用法: # @t.NoVTable # class AssignHandle(Mixin): # _CurrentClass: str # def __init__(self, trans): # self.InitMixin(trans) # self._CurrentClass = None # def Handle(self, node) -> int: # rhs = self.Trans.ExprH.HandleValue(node.value) # ... # ============================================================ @t.NoVTable class Mixin: """所有 Handle 的非多态基类:持有 Translator 回指针 + 共享委托方法""" Trans: HT.Translator | t.CPtr def InitMixin(self, trans: HT.Translator | t.CPtr) -> int: """初始化 Mixin 字段(子类 __init__ 中调用)""" self.Trans = trans return 0 # 全局 mbuddy 指针 _mbuddy: t.CVoid | t.CPtr