Files
TransPyV/App/lib/core/Handles/HandlesBase.py
2026-07-19 13:18:46 +08:00

263 lines
8.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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