From 29926747839fd95445a5a2c5cc98f0fd677599f3 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 5 Sep 2026 14:51:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(types):=20rowptr/REnum=20=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E5=B7=A5=E4=BD=9C=E5=8C=BA=E5=BF=AB=E7=85=A7=20+=20GS?= =?UTF-8?q?List/PrintModule=20=E4=B8=B4=E6=97=B6=20DBGCHAIN=20=E6=8A=A4?= =?UTF-8?q?=E6=A0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 把此前未提交的 rowptr 迁移整体入库(42 文件,含 ast/llvmlite/hashlib/json/zlib 等签名 rowptr 化)。临时诊断(用后移除):linkedlist.vp GSList[T].append 链完整性四检、__module.vp PrintModule Function.Params/param 指针野值护栏([DBGCHAIN] 前缀 + fflush + exit)。 --- asm.vp | 18 +- ast/__init__.vp | 26 +- ast/astaux.vp | 126 ++-- ast/base.vp | 87 +-- ast/exprs.vp | 570 ++++++++--------- ast/lexer.vp | 158 ++--- ast/match.vp | 166 ++--- ast/parser.vp | 1285 ++++++++++++++++++++------------------ ast/stmts.vp | 560 ++++++++--------- ast/tokens.vp | 90 +-- builtins.vp | 31 + hashlib/__init__.vp | 4 +- hashlib/__md5.vp | 52 +- hashlib/__sha1.vp | 48 +- hashlib/__sha256.vp | 58 +- hashlib/__sha512.vp | 98 +-- json/__init__.vp | 54 +- json/__parser.vp | 38 +- json/__writer.vp | 8 +- linkedlist.vp | 33 + llvmlite/__builder.vp | 952 ++++++++++++++-------------- llvmlite/__function.vp | 276 ++++---- llvmlite/__init__.vp | 174 +++--- llvmlite/__module.vp | 264 ++++---- llvmlite/__types.vp | 269 ++++---- llvmlite/__values.vp | 62 +- llvmlite/__verify.vp | 134 ++-- memhub.vp | 239 ++++--- openssl/ssl.vp | 9 +- openssl/types.vp | 89 +-- os/path.vp | 2 +- posix.vp | 2 +- socket.vp | 25 +- string.vp | 17 +- viperlib.vp | 16 +- vqt6/_bridge_widgets.cpp | 241 +++++-- vqt6/_bridge_widgets.h | 1 + vqt6/_qtwidgets.vp | 1 + w32/fileio.vp | 2 +- zipfile.vp | 132 ++-- zlib/zdeflate.vp | 27 +- zlib/zinflate.vp | 3 +- 42 files changed, 3506 insertions(+), 2941 deletions(-) diff --git a/asm.vp b/asm.vp index ae55d66..ef64063 100644 --- a/asm.vp +++ b/asm.vp @@ -18,15 +18,11 @@ def pause(): def inb(port: t.CUInt16T) -> t.CUInt8T: value: t.CUInt32T - # 显式 mov 到输出寄存器:EAX 作临时(CLOBBER_RAX 声明),避免 - # AsmOut 分配到非 RAX 时读到 asm 前残留(加 CLOBBER_RAX 后 LLVM - # 不再把 value 绑到 RAX,需 asm 内显式存值)。 c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)} in al, dx - movzx eax, al - mov {c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)}, eax""", + movzx eax, al""", out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)], - op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX]) + op =[t.ASM_DESCR.CLOBBER_RDX]) return t.CUInt8T(value) def outb(port: t.CUInt16T, value: t.CUInt8T): @@ -40,10 +36,9 @@ def inw(port: t.CUInt16T) -> t.CUInt16T: value: t.CUInt32T c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)} in ax, dx - movzx eax, ax - mov {c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)}, eax""", + movzx eax, ax""", out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)], - op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX]) + op =[t.ASM_DESCR.CLOBBER_RDX]) return t.CUInt16T(value) def outw(port: t.CUInt16T, value: t.CUInt16T): @@ -55,10 +50,9 @@ def outw(port: t.CUInt16T, value: t.CUInt16T): def inl(port: t.CUInt16T) -> t.CUInt32T: value: t.CUInt32T c.Asm(f"""mov edx, {c.AsmInp(t.CUInt32T(port), t.ASM_DESCR.REG_ANY)} - in eax, dx - mov {c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)}, eax""", + in eax, dx""", out = [c.AsmOut(value, t.ASM_DESCR.OUTPUT_REG)], - op =[t.ASM_DESCR.CLOBBER_RDX, t.ASM_DESCR.CLOBBER_RAX]) + op =[t.ASM_DESCR.CLOBBER_RDX]) return value def outl(port: t.CUInt16T, value: t.CUInt32T): diff --git a/ast/__init__.vp b/ast/__init__.vp index b87234a..05149af 100644 --- a/ast/__init__.vp +++ b/ast/__init__.vp @@ -37,9 +37,7 @@ from .exprs import ( Constant, NamedExpr, Attribute, Subscript, Starred, Name, List, Tuple, Slice, Call, Compare, OpNode, - # 字段访问辅助函数(TPV TypeGen 以 ast. 跨模块调用;未 re-export - # 时跨模块函数返回类型解析在 ast 包 text.ll 找不到定义(定义在 ast.exprs) - # → fail-fast "返回类型无法精确获取",如 attribute_get_attr/attribute_get_value) + name_get_id, constant_get_str_val, binop_get_left, binop_get_right, attribute_get_attr, attribute_get_value, @@ -65,14 +63,14 @@ from .parser import get_parse_err_line, get_parse_err_col, get_parse_err_msg # Global Memory Pool Pointer (follows project rules: declare _mbuddy) # User initializes in main: ast._mbuddy = memhub.MemBuddy(arena, size) # ============================================================ -_mbuddy: memhub.MemBuddy | t.CPtr +_mbuddy: rowptr[memhub.MemBuddy] # ============================================================ # Common API: parse # ============================================================ -def parse(src: str, pool: memhub.MemManager | t.CPtr) -> AST | t.CPtr: +def parse(src: str, pool: rowptr[memhub.MemManager]) -> rowptr[AST]: """Parse Python source code, return the AST Module node. Parameters: @@ -85,18 +83,18 @@ def parse(src: str, pool: memhub.MemManager | t.CPtr) -> AST | t.CPtr: if src is None or pool is None: return None _init_tables(pool) - lx: Lexer | t.CPtr = new_lexer(pool) + lx: rowptr[Lexer] = new_lexer(pool) if lx is None: return None _lexer_init(lx, src, pool) - tokens: Token | t.CPtr = tokenize(lx) + tokens: rowptr[Token] = tokenize(lx) if tokens is None: return None - tree: AST | t.CPtr = parse_tokens(pool, tokens) + tree: rowptr[AST] = parse_tokens(pool, tokens) return tree -def parse_expression(src: str, pool: memhub.MemManager | t.CPtr) -> AST | t.CPtr: +def parse_expression(src: str, pool: rowptr[memhub.MemManager]) -> rowptr[Expression]: """Parse a single expression, return the Expression node. Parameters: @@ -104,18 +102,18 @@ def parse_expression(src: str, pool: memhub.MemManager | t.CPtr) -> AST | t.CPtr pool: memhub.MemManager instance, to allocate AST nodes Returns: - Expression node, or None + Expression node (包装节点,body 字段为实际表达式), or None """ if src is None or pool is None: return None _init_tables(pool) - lx: Lexer | t.CPtr = new_lexer(pool) + lx: rowptr[Lexer] = new_lexer(pool) if lx is None: return None _lexer_init(lx, src, pool) - tokens: Token | t.CPtr = tokenize(lx) + tokens: rowptr[Token] = tokenize(lx) if tokens is None: return None - ps: Parser | t.CPtr = new_parser(pool) + ps: rowptr[Parser] = new_parser(pool) if ps is None: return None _parser_init(ps, tokens, pool) - body: AST | t.CPtr = _parse_test(ps) + body: rowptr[AST] = _parse_test(ps) return Expression(pool, body) diff --git a/ast/astaux.vp b/ast/astaux.vp index 3c51a00..06275a6 100644 --- a/ast/astaux.vp +++ b/ast/astaux.vp @@ -15,23 +15,23 @@ from .base import ( class ExceptHandler(AST): """ExceptHandler(type: AST, name: str)""" - type: AST | t.CPtr + type: rowptr[AST] name: str - def __new__(self, pool: memhub.MemManager | t.CPtr, - type: AST | t.CPtr, name: str): - ptr: ExceptHandler | t.CPtr = pool.alloc(ExceptHandler.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + type: rowptr[AST], name: str): + ptr: rowptr[ExceptHandler] = pool.alloc(ExceptHandler.__sizeof__()) if ptr: string.memset(ptr, 0, ExceptHandler.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - type: AST | t.CPtr, name: str): + def __init__(self, pool: rowptr[memhub.MemManager], + type: rowptr[AST], name: str): _init_ast(self, pool, 0, 0) self.type = type self.name = _copy_str(pool, name) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.ExceptHandler def type_name(self) -> str: @@ -59,27 +59,27 @@ class ExceptHandler(AST): class Arguments(AST): """Arguments(args: list[AST | CPtr], vararg: AST, kwarg: AST, defaults: list[AST | CPtr], kw_defaults: list[AST | CPtr])""" - args: list[AST | t.CPtr] | t.CPtr - vararg: AST | t.CPtr - kwarg: AST | t.CPtr - defaults: list[AST | t.CPtr] | t.CPtr - kw_defaults: list[AST | t.CPtr] | t.CPtr + args: rowptr[list[rowptr[AST]]] + vararg: rowptr[AST] + kwarg: rowptr[AST] + defaults: rowptr[list[rowptr[AST]]] + kw_defaults: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - args: list[AST | t.CPtr] | t.CPtr, - vararg: AST | t.CPtr, kwarg: AST | t.CPtr, - defaults: list[AST | t.CPtr] | t.CPtr, - kw_defaults: list[AST | t.CPtr] | t.CPtr): - ptr: Arguments | t.CPtr = pool.alloc(Arguments.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + args: rowptr[list[rowptr[AST]]], + vararg: rowptr[AST], kwarg: rowptr[AST], + defaults: rowptr[list[rowptr[AST]]], + kw_defaults: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Arguments] = pool.alloc(Arguments.__sizeof__()) if ptr: string.memset(ptr, 0, Arguments.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - args: list[AST | t.CPtr] | t.CPtr, - vararg: AST | t.CPtr, kwarg: AST | t.CPtr, - defaults: list[AST | t.CPtr] | t.CPtr, - kw_defaults: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + args: rowptr[list[rowptr[AST]]], + vararg: rowptr[AST], kwarg: rowptr[AST], + defaults: rowptr[list[rowptr[AST]]], + kw_defaults: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.args = args self.vararg = vararg @@ -90,7 +90,7 @@ class Arguments(AST): _set_parent_list(defaults, self) _set_parent_list(kw_defaults, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Arguments def type_name(self) -> str: @@ -125,22 +125,22 @@ class Arguments(AST): class Arg(AST): """Arg(arg: str, annotation: AST)""" arg: str - annotation: AST | t.CPtr + annotation: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - arg: str, annotation: AST | t.CPtr): - ptr: Arg | t.CPtr = pool.alloc(Arg.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + arg: str, annotation: rowptr[AST]): + ptr: rowptr[Arg] = pool.alloc(Arg.__sizeof__()) if ptr: string.memset(ptr, 0, Arg.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - arg: str, annotation: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + arg: str, annotation: rowptr[AST]): _init_ast(self, pool, 0, 0) self.arg = _copy_str(pool, arg) self.annotation = annotation - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Arg def type_name(self) -> str: @@ -166,22 +166,22 @@ class Arg(AST): class Keyword(AST): """Keyword(arg: str, value: AST)""" arg: str - value: AST | t.CPtr + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - arg: str, value: AST | t.CPtr): - ptr: Keyword | t.CPtr = pool.alloc(Keyword.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + arg: str, value: rowptr[AST]): + ptr: rowptr[Keyword] = pool.alloc(Keyword.__sizeof__()) if ptr: string.memset(ptr, 0, Keyword.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - arg: str, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + arg: str, value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.arg = _copy_str(pool, arg) self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Keyword def type_name(self) -> str: @@ -209,20 +209,20 @@ class Alias(AST): name: str asname: str - def __new__(self, pool: memhub.MemManager | t.CPtr, + def __new__(self, pool: rowptr[memhub.MemManager], name: str, asname: str): - ptr: Alias | t.CPtr = pool.alloc(Alias.__sizeof__()) + ptr: rowptr[Alias] = pool.alloc(Alias.__sizeof__()) if ptr: string.memset(ptr, 0, Alias.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, + def __init__(self, pool: rowptr[memhub.MemManager], name: str, asname: str): _init_ast(self, pool, 0, 0) self.name = _copy_str(pool, name) self.asname = _copy_str(pool, asname) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Alias def type_name(self) -> str: @@ -244,23 +244,23 @@ class Alias(AST): class WithItem(AST): """WithItem(context_expr: AST, optional_vars: AST)""" - context_expr: AST | t.CPtr - optional_vars: AST | t.CPtr + context_expr: rowptr[AST] + optional_vars: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - context_expr: AST | t.CPtr, optional_vars: AST | t.CPtr): - ptr: WithItem | t.CPtr = pool.alloc(WithItem.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + context_expr: rowptr[AST], optional_vars: rowptr[AST]): + ptr: rowptr[WithItem] = pool.alloc(WithItem.__sizeof__()) if ptr: string.memset(ptr, 0, WithItem.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - context_expr: AST | t.CPtr, optional_vars: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + context_expr: rowptr[AST], optional_vars: rowptr[AST]): _init_ast(self, pool, 0, 0) self.context_expr = context_expr self.optional_vars = optional_vars - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.WithItem def type_name(self) -> str: @@ -288,22 +288,22 @@ class WithItem(AST): class Comprehension(AST): """Comprehension(target: AST, iter: AST, ifs: list[AST | CPtr], is_async: CInt)""" - target: AST | t.CPtr - iter: AST | t.CPtr - ifs: list[AST | t.CPtr] | t.CPtr - is_async: t.CInt + target: rowptr[AST] + iter: rowptr[AST] + ifs: rowptr[list[rowptr[AST]]] + is_async: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, iter: AST | t.CPtr, - ifs: list[AST | t.CPtr] | t.CPtr, is_async: t.CInt): - ptr: Comprehension | t.CPtr = pool.alloc(Comprehension.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], iter: rowptr[AST], + ifs: rowptr[list[rowptr[AST]]], is_async: int): + ptr: rowptr[Comprehension] = pool.alloc(Comprehension.__sizeof__()) if ptr: string.memset(ptr, 0, Comprehension.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, iter: AST | t.CPtr, - ifs: list[AST | t.CPtr] | t.CPtr, is_async: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], iter: rowptr[AST], + ifs: rowptr[list[rowptr[AST]]], is_async: int): _init_ast(self, pool, 0, 0) self.target = target self.iter = iter @@ -311,7 +311,7 @@ class Comprehension(AST): self.is_async = is_async _set_parent_list(ifs, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Comprehension def type_name(self) -> str: @@ -332,6 +332,6 @@ class Comprehension(AST): pos = _emit(buf, size, pos, ", ifs=") pos = _dump_list(self.ifs, buf, size, pos) pos = _emit(buf, size, pos, ", is_async=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.is_async)) + pos = _emit_int(buf, size, pos, int64(self.is_async)) pos = _emit(buf, size, pos, ")") return pos diff --git a/ast/base.vp b/ast/base.vp index dd2d38d..0e60d5d 100644 --- a/ast/base.vp +++ b/ast/base.vp @@ -138,6 +138,8 @@ class OpKind(t.CEnum): UAdd: t.State USub: t.State Invert: t.State + Deref: t.State + AddrOf: t.State # None NoneOp: t.State @@ -156,6 +158,7 @@ FLAG_SIMPLE: t.CDefine = 2 FLAG_HAS_STAR: t.CDefine = 4 FLAG_IS_EXTERN: t.CDefine = 8 FLAG_IS_EXPORT: t.CDefine = 16 +FLAG_IS_DEFINE: t.CDefine = 32 # ============================================================ @@ -172,7 +175,7 @@ class ASTFlag(t.CEnum): # Helper Functions # ============================================================ -def _copy_str(pool: memhub.MemManager | t.CPtr, src: str) -> str: +def _copy_str(pool: rowptr[memhub.MemManager], src: str) -> str: """Allocate and copy a C string from pool.""" if src is None: return None slen: t.CSizeT = string.strlen(src) @@ -182,8 +185,8 @@ def _copy_str(pool: memhub.MemManager | t.CPtr, src: str) -> str: return buf -def _set_pos(node: AST | t.CPtr, lineno: t.CInt, col_offset: t.CInt, - end_lineno: t.CInt, end_col_offset: t.CInt): +def _set_pos(node: rowptr[AST], lineno: int, col_offset: int, + end_lineno: int, end_col_offset: int): if node is None: return node.lineno = lineno node.col_offset = col_offset @@ -191,7 +194,7 @@ def _set_pos(node: AST | t.CPtr, lineno: t.CInt, col_offset: t.CInt, node.end_col_offset = end_col_offset -def _inherit_pos(node: AST | t.CPtr, ref: AST | t.CPtr): +def _inherit_pos(node: rowptr[AST], ref: rowptr[AST]): if node is None or ref is None: return node.lineno = ref.lineno node.col_offset = ref.col_offset @@ -199,8 +202,8 @@ def _inherit_pos(node: AST | t.CPtr, ref: AST | t.CPtr): node.end_col_offset = ref.end_col_offset -def _init_ast(node: AST | t.CPtr, pool: memhub.MemManager | t.CPtr, - lineno: t.CInt, col: t.CInt): +def _init_ast(node: rowptr[AST], pool: rowptr[memhub.MemManager], + lineno: int, col: int): """Initialize AST base fields.""" node.parent = None node.pool = pool @@ -211,20 +214,20 @@ def _init_ast(node: AST | t.CPtr, pool: memhub.MemManager | t.CPtr, node.children = None -def _set_parent_list(lst: list[AST | t.CPtr] | t.CPtr, parent: AST | t.CPtr): +def _set_parent_list(lst: list[rowptr[AST]] | t.CPtr, parent: rowptr[AST]): """Set list children parent pointers.""" if lst is None: return n: t.CSizeT = lst.__len__() i: t.CSizeT = 0 while i < n: - child: AST | t.CPtr = lst.get(i) + child: rowptr[AST] = lst.get(i) if child is not None: child.parent = parent i += 1 -def _append_child(lst: list[AST | t.CPtr] | t.CPtr, node: AST | t.CPtr, - pool: memhub.MemManager | t.CPtr): +def _append_child(lst: list[rowptr[AST]] | t.CPtr, node: rowptr[AST], + pool: rowptr[memhub.MemManager]): """Append child nodes to a list (module-level function, to avoid conflicts with the AST.append method name). Call this function within the AST.append method to bypass the compiler mistaking list.append for a virtual function call to AST.append when doing type inference.""" @@ -237,7 +240,7 @@ def _append_child(lst: list[AST | t.CPtr] | t.CPtr, node: AST | t.CPtr, # Operator Mapping: TokOp -> OpKind # ============================================================ -def _binop_from_op(op_id: t.CInt) -> t.CInt: +def _binop_from_op(op_id: int) -> int: if op_id == TokOp.Plus: return OpKind.Add if op_id == TokOp.Minus: return OpKind.Sub if op_id == TokOp.Star: return OpKind.Mult @@ -254,7 +257,7 @@ def _binop_from_op(op_id: t.CInt) -> t.CInt: return OpKind.NoneOp -def _augop_from_op(op_id: t.CInt) -> t.CInt: +def _augop_from_op(op_id: int) -> int: if op_id == TokOp.PlusEq: return OpKind.Add if op_id == TokOp.MinusEq: return OpKind.Sub if op_id == TokOp.StarEq: return OpKind.Mult @@ -271,7 +274,7 @@ def _augop_from_op(op_id: t.CInt) -> t.CInt: return OpKind.NoneOp -def _cmpop_from_op(op_id: t.CInt) -> t.CInt: +def _cmpop_from_op(op_id: int) -> int: if op_id == TokOp.EqEq: return OpKind.Eq if op_id == TokOp.ExclaimEq: return OpKind.Ne if op_id == TokOp.Less: return OpKind.Lt @@ -285,46 +288,46 @@ def _cmpop_from_op(op_id: t.CInt) -> t.CInt: # dump Helper Functions # ============================================================ -def _emit(buf: t.CChar | t.CPtr, size: t.CSizeT, pos: t.CSizeT, +def _emit(buf: str, size: t.CSizeT, pos: t.CSizeT, text: str) -> t.CSizeT: """Append literal to buf+pos.""" if buf is None or pos >= size: return pos - cur: t.CChar | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(buf) + pos) + cur: str = str(uint64(buf) + pos) rem: t.CSizeT = size - pos - n: t.CInt = viperlib.snprintf(cur, rem, "%s", text) + n: int = viperlib.snprintf(cur, rem, "%s", text) if n < 0: return pos return pos + t.CSizeT(n) -def _emit_str(buf: t.CChar | t.CPtr, size: t.CSizeT, pos: t.CSizeT, +def _emit_str(buf: str, size: t.CSizeT, pos: t.CSizeT, text: str) -> t.CSizeT: """Append a string value to buf pos (using %s format)""" if buf is None or pos >= size: return pos - cur: t.CChar | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(buf) + pos) + cur: str = str(uint64(buf) + pos) rem: t.CSizeT = size - pos - n: t.CInt = viperlib.snprintf(cur, rem, "%s", text) + n: int = viperlib.snprintf(cur, rem, "%s", text) if n < 0: return pos return pos + t.CSizeT(n) -def _emit_int(buf: t.CChar | t.CPtr, size: t.CSizeT, pos: t.CSizeT, - val: t.CInt64T) -> t.CSizeT: +def _emit_int(buf: str, size: t.CSizeT, pos: t.CSizeT, + val: int64) -> t.CSizeT: """Append an integer value to buf pos (using %lld format).""" if buf is None or pos >= size: return pos - cur: t.CChar | t.CPtr = (t.CVoid | t.CPtr)(t.CUInt64T(buf) + pos) + cur: str = str(uint64(buf) + pos) rem: t.CSizeT = size - pos - n: t.CInt = viperlib.snprintf(cur, rem, "%lld", val) + n: int = viperlib.snprintf(cur, rem, "%lld", val) if n < 0: return pos return pos + t.CSizeT(n) -def _op_name(op: t.CInt) -> str: +def _op_name(op: int) -> str: """Return the string name of an OpKind.""" if op == OpKind.Add: return "Add" if op == OpKind.Sub: return "Sub" @@ -355,10 +358,12 @@ def _op_name(op: t.CInt) -> str: if op == OpKind.UAdd: return "UAdd" if op == OpKind.USub: return "USub" if op == OpKind.Invert: return "Invert" + if op == OpKind.Deref: return "Deref" + if op == OpKind.AddrOf: return "AddrOf" return "NoneOp" -def _dump_list(lst: list[AST | t.CPtr] | t.CPtr, buf: t.CChar | t.CPtr, +def _dump_list(lst: list[rowptr[AST]] | t.CPtr, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: """Traverse a list[AST | CPtr] container, polymorphically dump each element.""" if lst is None: @@ -370,7 +375,7 @@ def _dump_list(lst: list[AST | t.CPtr] | t.CPtr, buf: t.CChar | t.CPtr, while i < n: if i > 0: pos = _emit(buf, size, pos, ", ") - child: AST | t.CPtr = lst.get(i) + child: rowptr[AST] = lst.get(i) if child is not None: pos = child.dump(buf, size, pos) i += 1 @@ -378,20 +383,20 @@ def _dump_list(lst: list[AST | t.CPtr] | t.CPtr, buf: t.CChar | t.CPtr, return pos -def _dump_op_list(lst: t.CPtr, buf: t.CChar | t.CPtr, +def _dump_op_list(lst: t.CPtr, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: """Traverse a list[CInt] (OpKind values), output a list of op names.""" if lst is None: pos = _emit(buf, size, pos, "[]") return pos - ops_list: list[t.CInt] | t.CPtr = (list[t.CInt] | t.CPtr)(lst) + ops_list: rowptr[list[int]] = (rowptr[list[int]])(lst) pos = _emit(buf, size, pos, "[") n: t.CSizeT = ops_list.__len__() i: t.CSizeT = 0 while i < n: if i > 0: pos = _emit(buf, size, pos, ", ") - op: t.CInt = ops_list.get(i) + op: int = ops_list.get(i) pos = _emit(buf, size, pos, _op_name(op)) i += 1 pos = _emit(buf, size, pos, "]") @@ -417,15 +422,15 @@ class AST: end_lineno/end_col_offset: Ending position children: List of child nodes (body block, added via append) """ - parent: AST | t.CPtr - pool: memhub.MemManager | t.CPtr - lineno: t.CInt - col_offset: t.CInt - end_lineno: t.CInt - end_col_offset: t.CInt - children: list[AST | t.CPtr] | t.CPtr + parent: rowptr[AST] + pool: rowptr[memhub.MemManager] + lineno: int + col_offset: int + end_lineno: int + end_col_offset: int + children: list[rowptr[AST]] | t.CPtr - def kind(self) -> t.CInt: + def kind(self) -> int: """Returns the node type (ASTKind value), overridden by subclasses""" return 0 @@ -433,7 +438,7 @@ class AST: """Return the node type name, subclasses override""" return "AST" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: """Polymorphic dump: subclasses override to define custom format. Returns the written pos""" return pos @@ -443,7 +448,7 @@ class AST: Current implementation is empty. override this method to dispatch to visitor.visit_X(self)""" pass - def append(self, node: AST | t.CPtr): + def append(self, node: rowptr[AST]): """Append node to the children list. Used for parser to build statement blocks: module.append(stmt), if_node.append(stmt), etc. @@ -454,7 +459,7 @@ class AST: if self is None or node is None: return if self.children is None: - self.children = list[AST | t.CPtr](self.pool, 8) + self.children = list[rowptr[AST]](self.pool, 8) node.parent = self _append_child(self.children, node, self.pool) @@ -492,7 +497,7 @@ class ExprNode(AST): # Module dump function (for ast.dump(node, buf, size)) # ============================================================ -def dump(node: AST | t.CPtr, buf: t.CChar | t.CPtr, size: t.CSizeT): +def dump(node: rowptr[AST], buf: str, size: t.CSizeT): """Serialize AST node to buf (with capacity size)""" if node is None or buf is None or size == 0: return diff --git a/ast/exprs.vp b/ast/exprs.vp index 574ef7f..ad57b0f 100644 --- a/ast/exprs.vp +++ b/ast/exprs.vp @@ -18,28 +18,28 @@ from .base import ( class Name(ExprNode): """Name(id: str, ctx: ASTCtx)""" id: str - ctx: t.CInt + ctx: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - id: str, ctx: t.CInt): - ptr: Name | t.CPtr = pool.alloc(Name.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + id: str, ctx: int): + ptr: rowptr[Name] = pool.alloc(Name.__sizeof__()) if ptr: string.memset(ptr, 0, Name.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - id: str, ctx: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + id: str, ctx: int): _init_ast(self, pool, 0, 0) self.id = _copy_str(pool, id) self.ctx = ctx - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Name def type_name(self) -> str: return "Name" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Name(id='") pos = _emit_str(buf, size, pos, self.id) @@ -54,28 +54,28 @@ class Name(ExprNode): return pos -def name_get_id(node: Name | t.CPtr) -> str: +def name_get_id(node: rowptr[Name]) -> str: """获取 Name.id 字段(跨模块访问器,stub 字段访问陷阱防护)""" if node is None: return None return node.id -def constant_get_str_val(node: Constant | t.CPtr) -> str: +def constant_get_str_val(node: rowptr[Constant]) -> str: """获取 Constant.str_val 字段(跨模块访问器)""" if node is None: return None return node.str_val -def binop_get_left(node: BinOp | t.CPtr) -> AST | t.CPtr: +def binop_get_left(node: rowptr[BinOp]) -> rowptr[AST]: """获取 BinOp.left 字段(跨模块访问器)""" if node is None: return None return node.left -def binop_get_right(node: BinOp | t.CPtr) -> AST | t.CPtr: +def binop_get_right(node: rowptr[BinOp]) -> rowptr[AST]: """获取 BinOp.right 字段(跨模块访问器)""" if node is None: return None @@ -88,24 +88,24 @@ def binop_get_right(node: BinOp | t.CPtr) -> AST | t.CPtr: class Constant(ExprNode): """Constant(int_val/float_val/str_val, const_kind)""" - int_val: t.CInt64T - float_val: t.CDouble + int_val: int64 + float_val: double str_val: str - const_kind: t.CInt + const_kind: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - const_kind: t.CInt, int_val: t.CInt64T, - float_val: t.CDouble, str_val: str, - lineno: t.CInt, col: t.CInt): - ptr: Constant | t.CPtr = pool.alloc(Constant.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + const_kind: int, int_val: int64, + float_val: double, str_val: str, + lineno: int, col: int): + ptr: rowptr[Constant] = pool.alloc(Constant.__sizeof__()) if ptr: string.memset(ptr, 0, Constant.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - const_kind: t.CInt, int_val: t.CInt64T, - float_val: t.CDouble, str_val: str, - lineno: t.CInt, col: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + const_kind: int, int_val: int64, + float_val: double, str_val: str, + lineno: int, col: int): _init_ast(self, pool, lineno, col) self.const_kind = const_kind self.int_val = int_val @@ -115,13 +115,13 @@ class Constant(ExprNode): else: self.str_val = None - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Constant def type_name(self) -> str: return "Constant" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Constant(value=") if self.const_kind == CONST_INT: @@ -157,31 +157,31 @@ class Constant(ExprNode): class BinOp(ExprNode): """BinOp(left: AST, op: OpKind, right: AST)""" - left: AST | t.CPtr - op: t.CInt - right: AST | t.CPtr + left: rowptr[AST] + op: int + right: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - left: AST | t.CPtr, op: t.CInt, right: AST | t.CPtr): - ptr: BinOp | t.CPtr = pool.alloc(BinOp.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + left: rowptr[AST], op: int, right: rowptr[AST]): + ptr: rowptr[BinOp] = pool.alloc(BinOp.__sizeof__()) if ptr: string.memset(ptr, 0, BinOp.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - left: AST | t.CPtr, op: t.CInt, right: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + left: rowptr[AST], op: int, right: rowptr[AST]): _init_ast(self, pool, 0, 0) self.left = left self.op = op self.right = right - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.BinOp def type_name(self) -> str: return "BinOp" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "BinOp(left=") if self.left is not None: @@ -205,29 +205,29 @@ class BinOp(ExprNode): class UnaryOp(ExprNode): """UnaryOp(op: OpKind, operand: AST)""" - op: t.CInt - operand: AST | t.CPtr + op: int + operand: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - op: t.CInt, operand: AST | t.CPtr): - ptr: UnaryOp | t.CPtr = pool.alloc(UnaryOp.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + op: int, operand: rowptr[AST]): + ptr: rowptr[UnaryOp] = pool.alloc(UnaryOp.__sizeof__()) if ptr: string.memset(ptr, 0, UnaryOp.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - op: t.CInt, operand: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + op: int, operand: rowptr[AST]): _init_ast(self, pool, 0, 0) self.op = op self.operand = operand - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.UnaryOp def type_name(self) -> str: return "UnaryOp" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "UnaryOp(op=") pos = _emit(buf, size, pos, _op_name(self.op)) @@ -246,36 +246,36 @@ class UnaryOp(ExprNode): class Compare(ExprNode): """Compare(left: AST, ops: list[CInt], comparators: list[AST | CPtr])""" - left: AST | t.CPtr + left: rowptr[AST] ops: t.CPtr - comparators: list[AST | t.CPtr] | t.CPtr + comparators: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - left: AST | t.CPtr, + def __new__(self, pool: rowptr[memhub.MemManager], + left: rowptr[AST], ops: t.CPtr, - comparators: list[AST | t.CPtr] | t.CPtr): - ptr: Compare | t.CPtr = pool.alloc(Compare.__sizeof__()) + comparators: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Compare] = pool.alloc(Compare.__sizeof__()) if ptr: string.memset(ptr, 0, Compare.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - left: AST | t.CPtr, + def __init__(self, pool: rowptr[memhub.MemManager], + left: rowptr[AST], ops: t.CPtr, - comparators: list[AST | t.CPtr] | t.CPtr): + comparators: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.left = left self.ops = ops self.comparators = comparators _set_parent_list(comparators, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Compare def type_name(self) -> str: return "Compare" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Compare(left=") if self.left is not None: @@ -296,23 +296,23 @@ class Compare(ExprNode): class Call(ExprNode): """Call(func: AST, args: list[AST | CPtr], keywords: list[AST | CPtr])""" - func: AST | t.CPtr - args: list[AST | t.CPtr] | t.CPtr - keywords: list[AST | t.CPtr] | t.CPtr + func: rowptr[AST] + args: rowptr[list[rowptr[AST]]] + keywords: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - func: AST | t.CPtr, - args: list[AST | t.CPtr] | t.CPtr, - keywords: list[AST | t.CPtr] | t.CPtr): - ptr: Call | t.CPtr = pool.alloc(Call.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + func: rowptr[AST], + args: rowptr[list[rowptr[AST]]], + keywords: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Call] = pool.alloc(Call.__sizeof__()) if ptr: string.memset(ptr, 0, Call.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - func: AST | t.CPtr, - args: list[AST | t.CPtr] | t.CPtr, - keywords: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + func: rowptr[AST], + args: rowptr[list[rowptr[AST]]], + keywords: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.func = func self.args = args @@ -320,13 +320,13 @@ class Call(ExprNode): _set_parent_list(args, self) _set_parent_list(keywords, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Call def type_name(self) -> str: return "Call" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Call(func=") if self.func is not None: @@ -345,32 +345,32 @@ class Call(ExprNode): class BoolOp(ExprNode): """BoolOp(op: CInt, values: list[AST | CPtr])""" - op: t.CInt - values: list[AST | t.CPtr] | t.CPtr + op: int + values: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - op: t.CInt, - values: list[AST | t.CPtr] | t.CPtr): - ptr: BoolOp | t.CPtr = pool.alloc(BoolOp.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + op: int, + values: rowptr[list[rowptr[AST]]]): + ptr: rowptr[BoolOp] = pool.alloc(BoolOp.__sizeof__()) if ptr: string.memset(ptr, 0, BoolOp.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - op: t.CInt, - values: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + op: int, + values: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.op = op self.values = values _set_parent_list(values, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.BoolOp def type_name(self) -> str: return "BoolOp" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "BoolOp(op=") pos = _emit(buf, size, pos, _op_name(self.op)) @@ -386,29 +386,29 @@ class BoolOp(ExprNode): class Lambda(ExprNode): """Lambda(args: AST, body: AST)""" - args: AST | t.CPtr - body: AST | t.CPtr + args: rowptr[AST] + body: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - args: AST | t.CPtr, body: AST | t.CPtr): - ptr: Lambda | t.CPtr = pool.alloc(Lambda.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + args: rowptr[AST], body: rowptr[AST]): + ptr: rowptr[Lambda] = pool.alloc(Lambda.__sizeof__()) if ptr: string.memset(ptr, 0, Lambda.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - args: AST | t.CPtr, body: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + args: rowptr[AST], body: rowptr[AST]): _init_ast(self, pool, 0, 0) self.args = args self.body = body - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Lambda def type_name(self) -> str: return "Lambda" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Lambda(args=") if self.args is not None: @@ -430,33 +430,33 @@ class Lambda(ExprNode): class IfExp(ExprNode): """IfExp(test: AST, body: AST, orelse: AST)""" - test: AST | t.CPtr - body: AST | t.CPtr - orelse: AST | t.CPtr + test: rowptr[AST] + body: rowptr[AST] + orelse: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - test: AST | t.CPtr, body: AST | t.CPtr, - orelse: AST | t.CPtr): - ptr: IfExp | t.CPtr = pool.alloc(IfExp.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + test: rowptr[AST], body: rowptr[AST], + orelse: rowptr[AST]): + ptr: rowptr[IfExp] = pool.alloc(IfExp.__sizeof__()) if ptr: string.memset(ptr, 0, IfExp.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - test: AST | t.CPtr, body: AST | t.CPtr, - orelse: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + test: rowptr[AST], body: rowptr[AST], + orelse: rowptr[AST]): _init_ast(self, pool, 0, 0) self.test = test self.body = body self.orelse = orelse - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.IfExp def type_name(self) -> str: return "IfExp" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "IfExp(test=") if self.test is not None: @@ -483,33 +483,33 @@ class IfExp(ExprNode): class Dict(ExprNode): """Dict(keys: list[AST | CPtr], values: list[AST | CPtr])""" - keys: list[AST | t.CPtr] | t.CPtr - values: list[AST | t.CPtr] | t.CPtr + keys: rowptr[list[rowptr[AST]]] + values: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - keys: list[AST | t.CPtr] | t.CPtr, - values: list[AST | t.CPtr] | t.CPtr): - ptr: Dict | t.CPtr = pool.alloc(Dict.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + keys: rowptr[list[rowptr[AST]]], + values: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Dict] = pool.alloc(Dict.__sizeof__()) if ptr: string.memset(ptr, 0, Dict.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - keys: list[AST | t.CPtr] | t.CPtr, - values: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + keys: rowptr[list[rowptr[AST]]], + values: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.keys = keys self.values = values _set_parent_list(keys, self) _set_parent_list(values, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Dict def type_name(self) -> str: return "Dict" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Dict(keys=") pos = _dump_list(self.keys, buf, size, pos) @@ -525,28 +525,28 @@ class Dict(ExprNode): class Set(ExprNode): """Set(elts: list[AST | CPtr])""" - elts: list[AST | t.CPtr] | t.CPtr + elts: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - elts: list[AST | t.CPtr] | t.CPtr): - ptr: Set | t.CPtr = pool.alloc(Set.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + elts: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Set] = pool.alloc(Set.__sizeof__()) if ptr: string.memset(ptr, 0, Set.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - elts: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + elts: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.elts = elts _set_parent_list(elts, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Set def type_name(self) -> str: return "Set" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Set(elts=") pos = _dump_list(self.elts, buf, size, pos) @@ -560,32 +560,32 @@ class Set(ExprNode): class ListComp(ExprNode): """ListComp(elt: AST, generators: list[AST | CPtr])""" - elt: AST | t.CPtr - generators: list[AST | t.CPtr] | t.CPtr + elt: rowptr[AST] + generators: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - elt: AST | t.CPtr, - generators: list[AST | t.CPtr] | t.CPtr): - ptr: ListComp | t.CPtr = pool.alloc(ListComp.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + elt: rowptr[AST], + generators: rowptr[list[rowptr[AST]]]): + ptr: rowptr[ListComp] = pool.alloc(ListComp.__sizeof__()) if ptr: string.memset(ptr, 0, ListComp.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - elt: AST | t.CPtr, - generators: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + elt: rowptr[AST], + generators: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.elt = elt self.generators = generators _set_parent_list(generators, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.ListComp def type_name(self) -> str: return "ListComp" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "ListComp(elt=") if self.elt is not None: @@ -604,32 +604,32 @@ class ListComp(ExprNode): class SetComp(ExprNode): """SetComp(elt: AST, generators: list[AST | CPtr])""" - elt: AST | t.CPtr - generators: list[AST | t.CPtr] | t.CPtr + elt: rowptr[AST] + generators: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - elt: AST | t.CPtr, - generators: list[AST | t.CPtr] | t.CPtr): - ptr: SetComp | t.CPtr = pool.alloc(SetComp.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + elt: rowptr[AST], + generators: rowptr[list[rowptr[AST]]]): + ptr: rowptr[SetComp] = pool.alloc(SetComp.__sizeof__()) if ptr: string.memset(ptr, 0, SetComp.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - elt: AST | t.CPtr, - generators: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + elt: rowptr[AST], + generators: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.elt = elt self.generators = generators _set_parent_list(generators, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.SetComp def type_name(self) -> str: return "SetComp" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "SetComp(elt=") if self.elt is not None: @@ -648,34 +648,34 @@ class SetComp(ExprNode): class DictComp(ExprNode): """DictComp(key: AST, value: AST, generators: list[AST | CPtr])""" - key: AST | t.CPtr - value: AST | t.CPtr - generators: list[AST | t.CPtr] | t.CPtr + key: rowptr[AST] + value: rowptr[AST] + generators: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - key: AST | t.CPtr, value: AST | t.CPtr, - generators: list[AST | t.CPtr] | t.CPtr): - ptr: DictComp | t.CPtr = pool.alloc(DictComp.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + key: rowptr[AST], value: rowptr[AST], + generators: rowptr[list[rowptr[AST]]]): + ptr: rowptr[DictComp] = pool.alloc(DictComp.__sizeof__()) if ptr: string.memset(ptr, 0, DictComp.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - key: AST | t.CPtr, value: AST | t.CPtr, - generators: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + key: rowptr[AST], value: rowptr[AST], + generators: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.key = key self.value = value self.generators = generators _set_parent_list(generators, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.DictComp def type_name(self) -> str: return "DictComp" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "DictComp(key=") if self.key is not None: @@ -699,32 +699,32 @@ class DictComp(ExprNode): class GeneratorExp(ExprNode): """GeneratorExp(elt: AST, generators: list[AST | CPtr])""" - elt: AST | t.CPtr - generators: list[AST | t.CPtr] | t.CPtr + elt: rowptr[AST] + generators: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - elt: AST | t.CPtr, - generators: list[AST | t.CPtr] | t.CPtr): - ptr: GeneratorExp | t.CPtr = pool.alloc(GeneratorExp.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + elt: rowptr[AST], + generators: rowptr[list[rowptr[AST]]]): + ptr: rowptr[GeneratorExp] = pool.alloc(GeneratorExp.__sizeof__()) if ptr: string.memset(ptr, 0, GeneratorExp.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - elt: AST | t.CPtr, - generators: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + elt: rowptr[AST], + generators: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.elt = elt self.generators = generators _set_parent_list(generators, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.GeneratorExp def type_name(self) -> str: return "GeneratorExp" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "GeneratorExp(elt=") if self.elt is not None: @@ -743,25 +743,25 @@ class GeneratorExp(ExprNode): class Await(ExprNode): """Await(value: AST)""" - value: AST | t.CPtr + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): - ptr: Await | t.CPtr = pool.alloc(Await.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): + ptr: rowptr[Await] = pool.alloc(Await.__sizeof__()) if ptr: string.memset(ptr, 0, Await.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Await def type_name(self) -> str: return "Await" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Await(value=") if self.value is not None: @@ -778,25 +778,25 @@ class Await(ExprNode): class Yield(ExprNode): """Yield(value: AST)""" - value: AST | t.CPtr + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): - ptr: Yield | t.CPtr = pool.alloc(Yield.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): + ptr: rowptr[Yield] = pool.alloc(Yield.__sizeof__()) if ptr: string.memset(ptr, 0, Yield.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Yield def type_name(self) -> str: return "Yield" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Yield(value=") if self.value is not None: @@ -813,25 +813,25 @@ class Yield(ExprNode): class YieldFrom(ExprNode): """YieldFrom(value: AST)""" - value: AST | t.CPtr + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): - ptr: YieldFrom | t.CPtr = pool.alloc(YieldFrom.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): + ptr: rowptr[YieldFrom] = pool.alloc(YieldFrom.__sizeof__()) if ptr: string.memset(ptr, 0, YieldFrom.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.YieldFrom def type_name(self) -> str: return "YieldFrom" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "YieldFrom(value=") if self.value is not None: @@ -848,33 +848,33 @@ class YieldFrom(ExprNode): class FormattedValue(ExprNode): """FormattedValue(value: AST, conversion: CInt, format_spec: AST)""" - value: AST | t.CPtr - conversion: t.CInt - format_spec: AST | t.CPtr + value: rowptr[AST] + conversion: int + format_spec: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - value: AST | t.CPtr, conversion: t.CInt, - format_spec: AST | t.CPtr): - ptr: FormattedValue | t.CPtr = pool.alloc(FormattedValue.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + value: rowptr[AST], conversion: int, + format_spec: rowptr[AST]): + ptr: rowptr[FormattedValue] = pool.alloc(FormattedValue.__sizeof__()) if ptr: string.memset(ptr, 0, FormattedValue.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - value: AST | t.CPtr, conversion: t.CInt, - format_spec: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + value: rowptr[AST], conversion: int, + format_spec: rowptr[AST]): _init_ast(self, pool, 0, 0) self.value = value self.conversion = conversion self.format_spec = format_spec - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.FormattedValue def type_name(self) -> str: return "FormattedValue" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "FormattedValue(value=") if self.value is not None: @@ -882,7 +882,7 @@ class FormattedValue(ExprNode): else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", conversion=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.conversion)) + pos = _emit_int(buf, size, pos, int64(self.conversion)) pos = _emit(buf, size, pos, ", format_spec=") if self.format_spec is not None: pos = self.format_spec.dump(buf, size, pos) @@ -898,28 +898,28 @@ class FormattedValue(ExprNode): class JoinedStr(ExprNode): """JoinedStr(values: list[AST | CPtr])""" - values: list[AST | t.CPtr] | t.CPtr + values: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - values: list[AST | t.CPtr] | t.CPtr): - ptr: JoinedStr | t.CPtr = pool.alloc(JoinedStr.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + values: rowptr[list[rowptr[AST]]]): + ptr: rowptr[JoinedStr] = pool.alloc(JoinedStr.__sizeof__()) if ptr: string.memset(ptr, 0, JoinedStr.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - values: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + values: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.values = values _set_parent_list(values, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.JoinedStr def type_name(self) -> str: return "JoinedStr" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "JoinedStr(values=") pos = _dump_list(self.values, buf, size, pos) @@ -933,31 +933,31 @@ class JoinedStr(ExprNode): class Attribute(ExprNode): """Attribute(value: AST, attr: str, ctx: CInt)""" - value: AST | t.CPtr + value: rowptr[AST] attr: str - ctx: t.CInt + ctx: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - value: AST | t.CPtr, attr: str, ctx: t.CInt): - ptr: Attribute | t.CPtr = pool.alloc(Attribute.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + value: rowptr[AST], attr: str, ctx: int): + ptr: rowptr[Attribute] = pool.alloc(Attribute.__sizeof__()) if ptr: string.memset(ptr, 0, Attribute.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - value: AST | t.CPtr, attr: str, ctx: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + value: rowptr[AST], attr: str, ctx: int): _init_ast(self, pool, 0, 0) self.value = value self.attr = _copy_str(pool, attr) self.ctx = ctx - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Attribute def type_name(self) -> str: return "Attribute" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Attribute(value=") if self.value is not None: @@ -967,7 +967,7 @@ class Attribute(ExprNode): pos = _emit(buf, size, pos, ", attr='") pos = _emit_str(buf, size, pos, self.attr) pos = _emit(buf, size, pos, "', ctx=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.ctx)) + pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos @@ -979,14 +979,14 @@ class Attribute(ExprNode): # TPC 可能按 stub 类型生成错误 GEP(读垃圾地址 → 0xC0000005 崩溃)。 # 本模块是完整类型,字段偏移正确;跨模块调用方用这些访问器。 # ============================================================ -def attribute_get_value(node: Attribute | t.CPtr) -> AST | t.CPtr: +def attribute_get_value(node: rowptr[Attribute]) -> rowptr[AST]: """获取 Attribute.value 字段(跨模块访问器)""" if node is None: return None return node.value -def attribute_get_attr(node: Attribute | t.CPtr) -> str: +def attribute_get_attr(node: rowptr[Attribute]) -> str: """获取 Attribute.attr 字段(跨模块访问器)""" if node is None: return None @@ -999,31 +999,31 @@ def attribute_get_attr(node: Attribute | t.CPtr) -> str: class Subscript(ExprNode): """Subscript(value: AST, slice: AST, ctx: CInt)""" - value: AST | t.CPtr - slice: AST | t.CPtr - ctx: t.CInt + value: rowptr[AST] + slice: rowptr[AST] + ctx: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - value: AST | t.CPtr, slice: AST | t.CPtr, ctx: t.CInt): - ptr: Subscript | t.CPtr = pool.alloc(Subscript.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + value: rowptr[AST], slice: rowptr[AST], ctx: int): + ptr: rowptr[Subscript] = pool.alloc(Subscript.__sizeof__()) if ptr: string.memset(ptr, 0, Subscript.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - value: AST | t.CPtr, slice: AST | t.CPtr, ctx: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + value: rowptr[AST], slice: rowptr[AST], ctx: int): _init_ast(self, pool, 0, 0) self.value = value self.slice = slice self.ctx = ctx - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Subscript def type_name(self) -> str: return "Subscript" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Subscript(value=") if self.value is not None: @@ -1036,7 +1036,7 @@ class Subscript(ExprNode): else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", ctx=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.ctx)) + pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos @@ -1047,29 +1047,29 @@ class Subscript(ExprNode): class Starred(ExprNode): """Starred(value: AST, ctx: CInt)""" - value: AST | t.CPtr - ctx: t.CInt + value: rowptr[AST] + ctx: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - value: AST | t.CPtr, ctx: t.CInt): - ptr: Starred | t.CPtr = pool.alloc(Starred.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + value: rowptr[AST], ctx: int): + ptr: rowptr[Starred] = pool.alloc(Starred.__sizeof__()) if ptr: string.memset(ptr, 0, Starred.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - value: AST | t.CPtr, ctx: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + value: rowptr[AST], ctx: int): _init_ast(self, pool, 0, 0) self.value = value self.ctx = ctx - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Starred def type_name(self) -> str: return "Starred" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Starred(value=") if self.value is not None: @@ -1077,7 +1077,7 @@ class Starred(ExprNode): else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", ctx=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.ctx)) + pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos @@ -1088,35 +1088,35 @@ class Starred(ExprNode): class List(ExprNode): """List(elts: list[AST | CPtr], ctx: CInt)""" - elts: list[AST | t.CPtr] | t.CPtr - ctx: t.CInt + elts: rowptr[list[rowptr[AST]]] + ctx: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - elts: list[AST | t.CPtr] | t.CPtr, ctx: t.CInt): - ptr: List | t.CPtr = pool.alloc(List.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + elts: rowptr[list[rowptr[AST]]], ctx: int): + ptr: rowptr[List] = pool.alloc(List.__sizeof__()) if ptr: string.memset(ptr, 0, List.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - elts: list[AST | t.CPtr] | t.CPtr, ctx: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + elts: rowptr[list[rowptr[AST]]], ctx: int): _init_ast(self, pool, 0, 0) self.elts = elts self.ctx = ctx _set_parent_list(elts, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.List def type_name(self) -> str: return "List" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "List(elts=") pos = _dump_list(self.elts, buf, size, pos) pos = _emit(buf, size, pos, ", ctx=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.ctx)) + pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos @@ -1127,35 +1127,35 @@ class List(ExprNode): class Tuple(ExprNode): """Tuple(elts: list[AST | CPtr], ctx: CInt)""" - elts: list[AST | t.CPtr] | t.CPtr - ctx: t.CInt + elts: rowptr[list[rowptr[AST]]] + ctx: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - elts: list[AST | t.CPtr] | t.CPtr, ctx: t.CInt): - ptr: Tuple | t.CPtr = pool.alloc(Tuple.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + elts: rowptr[list[rowptr[AST]]], ctx: int): + ptr: rowptr[Tuple] = pool.alloc(Tuple.__sizeof__()) if ptr: string.memset(ptr, 0, Tuple.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - elts: list[AST | t.CPtr] | t.CPtr, ctx: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + elts: rowptr[list[rowptr[AST]]], ctx: int): _init_ast(self, pool, 0, 0) self.elts = elts self.ctx = ctx _set_parent_list(elts, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Tuple def type_name(self) -> str: return "Tuple" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Tuple(elts=") pos = _dump_list(self.elts, buf, size, pos) pos = _emit(buf, size, pos, ", ctx=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.ctx)) + pos = _emit_int(buf, size, pos, int64(self.ctx)) pos = _emit(buf, size, pos, ")") return pos @@ -1166,33 +1166,33 @@ class Tuple(ExprNode): class Slice(ExprNode): """Slice(lower: AST, upper: AST, step: AST)""" - lower: AST | t.CPtr - upper: AST | t.CPtr - step: AST | t.CPtr + lower: rowptr[AST] + upper: rowptr[AST] + step: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - lower: AST | t.CPtr, upper: AST | t.CPtr, - step: AST | t.CPtr): - ptr: Slice | t.CPtr = pool.alloc(Slice.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + lower: rowptr[AST], upper: rowptr[AST], + step: rowptr[AST]): + ptr: rowptr[Slice] = pool.alloc(Slice.__sizeof__()) if ptr: string.memset(ptr, 0, Slice.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - lower: AST | t.CPtr, upper: AST | t.CPtr, - step: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + lower: rowptr[AST], upper: rowptr[AST], + step: rowptr[AST]): _init_ast(self, pool, 0, 0) self.lower = lower self.upper = upper self.step = step - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Slice def type_name(self) -> str: return "Slice" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Slice(lower=") if self.lower is not None: @@ -1219,29 +1219,29 @@ class Slice(ExprNode): class NamedExpr(ExprNode): """NamedExpr(target: AST, value: AST)""" - target: AST | t.CPtr - value: AST | t.CPtr + target: rowptr[AST] + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, value: AST | t.CPtr): - ptr: NamedExpr | t.CPtr = pool.alloc(NamedExpr.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], value: rowptr[AST]): + ptr: rowptr[NamedExpr] = pool.alloc(NamedExpr.__sizeof__()) if ptr: string.memset(ptr, 0, NamedExpr.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.target = target self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.NamedExpr def type_name(self) -> str: return "NamedExpr" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "NamedExpr(target=") if self.target is not None: @@ -1263,25 +1263,25 @@ class NamedExpr(ExprNode): class OpNode(AST): """OpNode(op: CInt)""" - op: t.CInt + op: int - def __new__(self, pool: memhub.MemManager | t.CPtr, op: t.CInt): - ptr: OpNode | t.CPtr = pool.alloc(OpNode.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], op: int): + ptr: rowptr[OpNode] = pool.alloc(OpNode.__sizeof__()) if ptr: string.memset(ptr, 0, OpNode.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, op: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], op: int): _init_ast(self, pool, 0, 0) self.op = op - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.OpNode def type_name(self) -> str: return "OpNode" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "OpNode(op=") pos = _emit(buf, size, pos, _op_name(self.op)) diff --git a/ast/lexer.vp b/ast/lexer.vp index 2818c43..adfb893 100644 --- a/ast/lexer.vp +++ b/ast/lexer.vp @@ -19,31 +19,31 @@ class Lexer: src: str # Source code (NUL-terminated) pos: t.CSizeT # Current position len: t.CSizeT # Source code length - lineno: t.CInt # Current line number (1-based) - col: t.CInt # Current column number (0-based) - pool: memhub.MemManager | t.CPtr # Memory pool - indent_stack: t.CInt | t.CPtr # Indent stack (int array, allocated from pool) - indent_top: t.CInt # Stack top (-1 for empty stack) - paren_depth: t.CInt # Paren depth (>0 for no TokenType.NewLine) - tokens_head: Token | t.CPtr # token list head - tokens_tail: Token | t.CPtr # token list tail - at_line_start: t.CInt # 1=line start (need indent) - error_count: t.CInt # Error count + lineno: int # Current line number (1-based) + col: int # Current column number (0-based) + pool: rowptr[memhub.MemManager] # Memory pool + indent_stack: rowptr[int] # Indent stack (int array, allocated from pool) + indent_top: int # Stack top (-1 for empty stack) + paren_depth: int # Paren depth (>0 for no TokenType.NewLine) + tokens_head: rowptr[Token] # token list head + tokens_tail: rowptr[Token] # token list tail + at_line_start: int # 1=line start (need indent) + error_count: int # Error count - def __new__(self, pool: memhub.MemManager | t.CPtr): - ptr: Lexer | t.CPtr = pool.alloc(Lexer.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager]): + ptr: rowptr[Lexer] = pool.alloc(Lexer.__sizeof__()) if ptr: string.memset(ptr, 0, Lexer.__sizeof__()) return ptr -def new_lexer(pool: memhub.MemManager | t.CPtr) -> Lexer | t.CPtr: +def new_lexer(pool: rowptr[memhub.MemManager]) -> rowptr[Lexer]: """Allocate from the pool and return a Lexer (cross-module safe wrapper)""" return Lexer(pool) -def _lexer_init(lx: Lexer | t.CPtr, src: str, - pool: memhub.MemManager | t.CPtr): +def _lexer_init(lx: rowptr[Lexer], src: str, + pool: rowptr[memhub.MemManager]): """Initialize Lexer""" if lx == None: return lx.src = src @@ -73,7 +73,7 @@ def _lexer_init(lx: Lexer | t.CPtr, src: str, # Auxiliary Functions # ============================================================ -def _peek(lx: Lexer | t.CPtr, offset: t.CSizeT) -> t.CChar: +def _peek(lx: rowptr[Lexer], offset: t.CSizeT) -> t.CChar: """Peek character at position pos+offset, return '\0' if out of bounds""" p: t.CSizeT = lx.pos + offset if p >= lx.len: @@ -81,13 +81,13 @@ def _peek(lx: Lexer | t.CPtr, offset: t.CSizeT) -> t.CChar: return lx.src[p] -def _peek_cur(lx: Lexer | t.CPtr) -> t.CChar: +def _peek_cur(lx: rowptr[Lexer]) -> t.CChar: if lx.pos >= lx.len: return '\0' return lx.src[lx.pos] -def _advance(lx: Lexer | t.CPtr) -> t.CChar: +def _advance(lx: rowptr[Lexer]) -> t.CChar: """Advance one character, return the character""" if lx.pos >= lx.len: return '\0' @@ -101,40 +101,40 @@ def _advance(lx: Lexer | t.CPtr) -> t.CChar: return ch -def _is_alpha(ch: t.CChar) -> t.CInt: +def _is_alpha(ch: t.CChar) -> int: if ch >= 'a' and ch <= 'z': return 1 if ch >= 'A' and ch <= 'Z': return 1 if ch == '_': return 1 return 0 -def _is_digit(ch: t.CChar) -> t.CInt: +def _is_digit(ch: t.CChar) -> int: if ch >= '0' and ch <= '9': return 1 return 0 -def _is_alnum(ch: t.CChar) -> t.CInt: +def _is_alnum(ch: t.CChar) -> int: if _is_alpha(ch): return 1 if _is_digit(ch): return 1 return 0 -def _is_hex(ch: t.CChar) -> t.CInt: +def _is_hex(ch: t.CChar) -> int: if ch >= '0' and ch <= '9': return 1 if ch >= 'a' and ch <= 'f': return 1 if ch >= 'A' and ch <= 'F': return 1 return 0 -def _hex_val(ch: t.CChar) -> t.CInt: +def _hex_val(ch: t.CChar) -> int: """十六进制字符转数值 0-15(供 \xNN 转义解析)""" - if ch >= '0' and ch <= '9': return t.CInt(ch) - 48 - if ch >= 'a' and ch <= 'f': return t.CInt(ch) - 87 - if ch >= 'A' and ch <= 'F': return t.CInt(ch) - 55 + if ch >= '0' and ch <= '9': return int(ch) - 48 + if ch >= 'a' and ch <= 'f': return int(ch) - 87 + if ch >= 'A' and ch <= 'F': return int(ch) - 55 return 0 -def _is_space(ch: t.CChar) -> t.CInt: +def _is_space(ch: t.CChar) -> int: if ch == ' ': return 1 if ch == '\t': return 1 if ch == '\f': return 1 @@ -143,7 +143,7 @@ def _is_space(ch: t.CChar) -> t.CInt: return 0 -def _emit(lx: Lexer | t.CPtr, tok: Token | t.CPtr): +def _emit(lx: rowptr[Lexer], tok: rowptr[Token]): """Append token to token list""" if tok == None: return if lx.tokens_head == None: @@ -154,9 +154,9 @@ def _emit(lx: Lexer | t.CPtr, tok: Token | t.CPtr): lx.tokens_tail = tok -def _make_op_token(lx: Lexer | t.CPtr, op_id: t.CInt, length: t.CInt, - lineno: t.CInt, col: t.CInt) -> Token | t.CPtr: - tok: Token | t.CPtr = new_token(lx.pool, TokenType.Op, lineno, col) +def _make_op_token(lx: rowptr[Lexer], op_id: int, length: int, + lineno: int, col: int) -> rowptr[Token]: + tok: rowptr[Token] = new_token(lx.pool, TokenType.Op, lineno, col) if tok == None: return None tok.op_subtype = op_id tok.end_col_offset = col + length @@ -167,14 +167,14 @@ def _make_op_token(lx: Lexer | t.CPtr, op_id: t.CInt, length: t.CInt, # Indent Handling # ============================================================ -def _handle_indent(lx: Lexer | t.CPtr): +def _handle_indent(lx: rowptr[Lexer]): """Handle line start indent, generate TokenType.Indent/TokenType.Dedent. Skip empty lines and comment lines.""" # Skip empty lines and comment lines while lx.pos < lx.len: # Save line start position for non-empty lines line_start_pos: t.CSizeT = lx.pos - line_start_col: t.CInt = lx.col + line_start_col: int = lx.col # Skip whitespace, not across lines while lx.pos < lx.len: ch: t.CChar = lx.src[lx.pos] @@ -219,9 +219,9 @@ def _handle_indent(lx: Lexer | t.CPtr): return # Calculate current line indent - indent: t.CInt = 0 + indent: int = 0 save_pos: t.CSizeT = lx.pos - save_col: t.CInt = lx.col + save_col: int = lx.col while lx.pos < lx.len: ch: t.CChar = lx.src[lx.pos] if ch == ' ': @@ -246,7 +246,7 @@ def _handle_indent(lx: Lexer | t.CPtr): return # Compare indent with top of indent stack - top_indent: t.CInt = lx.indent_stack[lx.indent_top] + top_indent: int = lx.indent_stack[lx.indent_top] if indent > top_indent: # TokenType.Indent if lx.indent_top + 1 >= LEXER_MAX_INDENT: @@ -254,12 +254,12 @@ def _handle_indent(lx: Lexer | t.CPtr): return lx.indent_top += 1 lx.indent_stack[lx.indent_top] = indent - tok: Token | t.CPtr = new_token(lx.pool, TokenType.Indent, lx.lineno, 0) + tok: rowptr[Token] = new_token(lx.pool, TokenType.Indent, lx.lineno, 0) _emit(lx, tok) else: while indent < lx.indent_stack[lx.indent_top] and lx.indent_top > 0: lx.indent_top -= 1 - tok: Token | t.CPtr = new_token(lx.pool, TokenType.Dedent, lx.lineno, 0) + tok: rowptr[Token] = new_token(lx.pool, TokenType.Dedent, lx.lineno, 0) _emit(lx, tok) lx.at_line_start = 0 @@ -268,10 +268,10 @@ def _handle_indent(lx: Lexer | t.CPtr): # Identifier/Keyword Handling # ============================================================ -def _read_name(lx: Lexer | t.CPtr): +def _read_name(lx: rowptr[Lexer]): start: t.CSizeT = lx.pos - start_lineno: t.CInt = lx.lineno - start_col: t.CInt = lx.col + start_lineno: int = lx.lineno + start_col: int = lx.col while lx.pos < lx.len: ch: t.CChar = lx.src[lx.pos] if _is_alnum(ch): @@ -280,13 +280,13 @@ def _read_name(lx: Lexer | t.CPtr): else: break length: t.CSizeT = lx.pos - start - tok: Token | t.CPtr = new_token(lx.pool, TokenType.Name, start_lineno, start_col) + tok: rowptr[Token] = new_token(lx.pool, TokenType.Name, start_lineno, start_col) if tok == None: return token_set_str(lx.pool, tok, lx.src, start, length) tok.end_lineno = lx.lineno - tok.end_col_offset = start_col + t.CInt(length) + tok.end_col_offset = start_col + int(length) # Look up keyword if any - kw_id: t.CInt = _kw_lookup(tok.str_val) + kw_id: int = _kw_lookup(tok.str_val) if kw_id: tok.kw_subtype = kw_id _emit(lx, tok) @@ -296,12 +296,12 @@ def _read_name(lx: Lexer | t.CPtr): # Number Handling # ============================================================ -def _read_number(lx: Lexer | t.CPtr): +def _read_number(lx: rowptr[Lexer]): start: t.CSizeT = lx.pos - start_lineno: t.CInt = lx.lineno - start_col: t.CInt = lx.col - is_float: t.CInt = 0 - is_complex: t.CInt = 0 + start_lineno: int = lx.lineno + start_col: int = lx.col + is_float: int = 0 + is_complex: int = 0 ch0: t.CChar = lx.src[lx.pos] # Handle 0x/0o/0b prefix @@ -399,17 +399,17 @@ def _read_number(lx: Lexer | t.CPtr): _emit_number(lx, start, start_lineno, start_col, is_float, is_complex, 0) -def _emit_number(lx: Lexer | t.CPtr, start: t.CSizeT, - start_lineno: t.CInt, start_col: t.CInt, - is_float: t.CInt, is_complex: t.CInt, is_hex: t.CInt): +def _emit_number(lx: rowptr[Lexer], start: t.CSizeT, + start_lineno: int, start_col: int, + is_float: int, is_complex: int, is_hex: int): length: t.CSizeT = lx.pos - start - tok: Token | t.CPtr = new_token(lx.pool, TokenType.Number, start_lineno, start_col) + tok: rowptr[Token] = new_token(lx.pool, TokenType.Number, start_lineno, start_col) if tok == None: return token_set_str(lx.pool, tok, lx.src, start, length) tok.is_float = is_float tok.is_complex = is_complex tok.end_lineno = lx.lineno - tok.end_col_offset = start_col + t.CInt(length) + tok.end_col_offset = start_col + int(length) # Parse number if is_float: tok.float_val = string.atof(tok.str_val) @@ -422,19 +422,19 @@ def _emit_number(lx: Lexer | t.CPtr, start: t.CSizeT, # String Handling # ============================================================ -def _read_string(lx: Lexer | t.CPtr): +def _read_string(lx: rowptr[Lexer]): """Read string literal. Supports prefixes: r, b, u, f, rb, br, rf, fr (case insensitive) Supports quotes: ', ", ''', Later we need to support string prefixes like i16/i24""" - start_lineno: t.CInt = lx.lineno - start_col: t.CInt = lx.col + start_lineno: int = lx.lineno + start_col: int = lx.col prefix_start: t.CSizeT = lx.pos # Read prefix (r/b/u/f) - is_raw: t.CInt = 0 - is_bytes: t.CInt = 0 - is_fstring: t.CInt = 0 + is_raw: int = 0 + is_bytes: int = 0 + is_fstring: int = 0 while lx.pos < lx.len: ch: t.CChar = lx.src[lx.pos] if ch == 'r' or ch == 'R': @@ -466,7 +466,7 @@ def _read_string(lx: Lexer | t.CPtr): return # Check triple quote - is_triple: t.CInt = 0 + is_triple: int = 0 if lx.pos + 2 < lx.len: if lx.src[lx.pos] == quote and lx.src[lx.pos + 1] == quote and lx.src[lx.pos + 2] == quote: is_triple = 1 @@ -482,7 +482,7 @@ def _read_string(lx: Lexer | t.CPtr): # Read string content content_buf_start: t.CSizeT = lx.pos # f-string {} 表达式块嵌套深度(PEP 701 同引号嵌套字符串支持用) - fstr_depth: t.CInt = 0 + fstr_depth: int = 0 while lx.pos < lx.len: ch = lx.src[lx.pos] if is_triple: @@ -582,7 +582,7 @@ def _read_string(lx: Lexer | t.CPtr): lx.col += 1 # Create token - tok: Token | t.CPtr = new_token(lx.pool, TokenType.String, start_lineno, start_col) + tok: rowptr[Token] = new_token(lx.pool, TokenType.String, start_lineno, start_col) if tok == None: return content_len: t.CSizeT = content_end - content_buf_start # esc_len: Actual bytes after escaping (used to check single character) @@ -632,7 +632,7 @@ def _read_string(lx: Lexer | t.CPtr): h1: t.CChar = lx.src[content_buf_start + rpos + 1] h2: t.CChar = lx.src[content_buf_start + rpos + 2] if _is_hex(h1) != 0 and _is_hex(h2) != 0: - hex_v: t.CInt = (_hex_val(h1) << 4) | _hex_val(h2) + hex_v: int = (_hex_val(h1) << 4) | _hex_val(h2) conv_buf[wpos] = t.CChar(hex_v) wpos += 1 rpos += 3 @@ -677,20 +677,20 @@ def _read_string(lx: Lexer | t.CPtr): # Operator Matching # ============================================================ -def _read_operator(lx: Lexer | t.CPtr): +def _read_operator(lx: rowptr[Lexer]): """Greedy match operator""" - start_lineno: t.CInt = lx.lineno - start_col: t.CInt = lx.col + start_lineno: int = lx.lineno + start_col: int = lx.col remaining: t.CSizeT = lx.len - lx.pos # Traverse operator table, find longest match - best_entry: OpEntry | t.CPtr = None - best_len: t.CInt = 0 - cur: OpEntry | t.CPtr = _op_head + best_entry: rowptr[OpEntry] = None + best_len: int = 0 + cur: rowptr[OpEntry] = _op_head while cur != None: - if cur.length <= t.CInt(remaining): + if cur.length <= int(remaining): # Compare cur.name with src[pos:pos+cur.length] - match: t.CInt = 1 + match: int = 1 i: t.CSizeT = 0 while i < t.CSizeT(cur.length): if lx.src[lx.pos + i] != cur.name[i]: @@ -717,7 +717,7 @@ def _read_operator(lx: Lexer | t.CPtr): if lx.paren_depth > 0: lx.paren_depth -= 1 - tok: Token | t.CPtr = _make_op_token(lx, best_entry.op_id, best_entry.length, + tok: rowptr[Token] = _make_op_token(lx, best_entry.op_id, best_entry.length, start_lineno, start_col) if tok == None: return token_set_str(lx.pool, tok, lx.src, lx.pos, t.CSizeT(best_len)) @@ -730,7 +730,7 @@ def _read_operator(lx: Lexer | t.CPtr): # Main Lexical Analysis Entry Point # ============================================================ -def tokenize(lx: Lexer | t.CPtr) -> Token | t.CPtr: +def tokenize(lx: rowptr[Lexer]) -> rowptr[Token]: """Execute tokenization, return token list head""" if lx == None: return None while lx.pos < lx.len: @@ -748,11 +748,11 @@ def tokenize(lx: Lexer | t.CPtr) -> Token | t.CPtr: if ch == '\n': if lx.paren_depth > 0: # # In bi brackets, generates TokenType.Nl - tok: Token | t.CPtr = new_token(lx.pool, TokenType.Nl, lx.lineno, lx.col) + tok: rowptr[Token] = new_token(lx.pool, TokenType.Nl, lx.lineno, lx.col) _emit(lx, tok) else: # Logical new line - tok: Token | t.CPtr = new_token(lx.pool, TokenType.NewLine, lx.lineno, lx.col) + tok: rowptr[Token] = new_token(lx.pool, TokenType.NewLine, lx.lineno, lx.col) _emit(lx, tok) lx.at_line_start = 1 lx.pos += 1 @@ -828,17 +828,17 @@ def tokenize(lx: Lexer | t.CPtr) -> Token | t.CPtr: # End of file: generate TokenType.NewLine (if there's content) if lx.tokens_tail != None: if lx.tokens_tail.type != TokenType.NewLine and lx.tokens_tail.type != TokenType.Nl: - tok: Token | t.CPtr = new_token(lx.pool, TokenType.NewLine, lx.lineno, lx.col) + tok: rowptr[Token] = new_token(lx.pool, TokenType.NewLine, lx.lineno, lx.col) _emit(lx, tok) # Generate remaining remaining TokenType.Dedent while lx.indent_top > 0: lx.indent_top -= 1 - tok: Token | t.CPtr = new_token(lx.pool, TokenType.Dedent, lx.lineno, 0) + tok: rowptr[Token] = new_token(lx.pool, TokenType.Dedent, lx.lineno, 0) _emit(lx, tok) # TokenType.EndMarker - tok: Token | t.CPtr = new_token(lx.pool, TokenType.EndMarker, lx.lineno, 0) + tok: rowptr[Token] = new_token(lx.pool, TokenType.EndMarker, lx.lineno, 0) _emit(lx, tok) return lx.tokens_head diff --git a/ast/match.vp b/ast/match.vp index 7e78378..733c6b7 100644 --- a/ast/match.vp +++ b/ast/match.vp @@ -15,29 +15,29 @@ from .base import ( class MatchCase(AST): """MatchCase(pattern: AST, guard: AST)""" - pattern: AST | t.CPtr - guard: AST | t.CPtr + pattern: rowptr[AST] + guard: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - pattern: AST | t.CPtr, guard: AST | t.CPtr): - ptr: MatchCase | t.CPtr = pool.alloc(MatchCase.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + pattern: rowptr[AST], guard: rowptr[AST]): + ptr: rowptr[MatchCase] = pool.alloc(MatchCase.__sizeof__()) if ptr: string.memset(ptr, 0, MatchCase.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - pattern: AST | t.CPtr, guard: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + pattern: rowptr[AST], guard: rowptr[AST]): _init_ast(self, pool, 0, 0) self.pattern = pattern self.guard = guard - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchCase def type_name(self) -> str: return "MatchCase" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchCase(pattern=") if self.pattern is not None: @@ -57,25 +57,25 @@ class MatchCase(AST): class MatchValue(AST): """MatchValue(value: AST)""" - value: AST | t.CPtr + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): - ptr: MatchValue | t.CPtr = pool.alloc(MatchValue.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): + ptr: rowptr[MatchValue] = pool.alloc(MatchValue.__sizeof__()) if ptr: string.memset(ptr, 0, MatchValue.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchValue def type_name(self) -> str: return "MatchValue" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchValue(value=") if self.value is not None: @@ -90,25 +90,25 @@ class MatchValue(AST): class MatchSingleton(AST): """MatchSingleton(value: AST)""" - value: AST | t.CPtr + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): - ptr: MatchSingleton | t.CPtr = pool.alloc(MatchSingleton.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): + ptr: rowptr[MatchSingleton] = pool.alloc(MatchSingleton.__sizeof__()) if ptr: string.memset(ptr, 0, MatchSingleton.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchSingleton def type_name(self) -> str: return "MatchSingleton" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchSingleton(value=") if self.value is not None: @@ -122,29 +122,29 @@ class MatchSingleton(AST): # ============================================================ class MatchSequence(AST): - """MatchSequence(patterns: list[AST | t.CPtr])""" - patterns: list[AST | t.CPtr] | t.CPtr + """MatchSequence(patterns: list[rowptr[AST]])""" + patterns: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - patterns: list[AST | t.CPtr] | t.CPtr): - ptr: MatchSequence | t.CPtr = pool.alloc(MatchSequence.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + patterns: rowptr[list[rowptr[AST]]]): + ptr: rowptr[MatchSequence] = pool.alloc(MatchSequence.__sizeof__()) if ptr: string.memset(ptr, 0, MatchSequence.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - patterns: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + patterns: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.patterns = patterns _set_parent_list(patterns, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchSequence def type_name(self) -> str: return "MatchSequence" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchSequence(patterns=") pos = _dump_list(self.patterns, buf, size, pos) @@ -157,23 +157,23 @@ class MatchSequence(AST): # ============================================================ class MatchMapping(AST): - """MatchMapping(keys: list[AST | t.CPtr], patterns: list[AST | t.CPtr], rest: str)""" - keys: list[AST | t.CPtr] | t.CPtr - patterns: list[AST | t.CPtr] | t.CPtr + """MatchMapping(keys: list[rowptr[AST]], patterns: list[rowptr[AST]], rest: str)""" + keys: rowptr[list[rowptr[AST]]] + patterns: rowptr[list[rowptr[AST]]] rest: str - def __new__(self, pool: memhub.MemManager | t.CPtr, - keys: list[AST | t.CPtr] | t.CPtr, - patterns: list[AST | t.CPtr] | t.CPtr, + def __new__(self, pool: rowptr[memhub.MemManager], + keys: rowptr[list[rowptr[AST]]], + patterns: rowptr[list[rowptr[AST]]], rest: str): - ptr: MatchMapping | t.CPtr = pool.alloc(MatchMapping.__sizeof__()) + ptr: rowptr[MatchMapping] = pool.alloc(MatchMapping.__sizeof__()) if ptr: string.memset(ptr, 0, MatchMapping.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - keys: list[AST | t.CPtr] | t.CPtr, - patterns: list[AST | t.CPtr] | t.CPtr, + def __init__(self, pool: rowptr[memhub.MemManager], + keys: rowptr[list[rowptr[AST]]], + patterns: rowptr[list[rowptr[AST]]], rest: str): _init_ast(self, pool, 0, 0) self.keys = keys @@ -182,13 +182,13 @@ class MatchMapping(AST): _set_parent_list(keys, self) _set_parent_list(patterns, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchMapping def type_name(self) -> str: return "MatchMapping" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchMapping(keys=") pos = _dump_list(self.keys, buf, size, pos) @@ -205,28 +205,28 @@ class MatchMapping(AST): # ============================================================ class MatchClass(AST): - """MatchClass(cls: AST, patterns: list[AST | t.CPtr], - kwd_attrs: list[AST | t.CPtr], kwd_patterns: list[AST | t.CPtr])""" - cls: AST | t.CPtr - patterns: list[AST | t.CPtr] | t.CPtr - kwd_attrs: list[AST | t.CPtr] | t.CPtr - kwd_patterns: list[AST | t.CPtr] | t.CPtr + """MatchClass(cls: AST, patterns: list[rowptr[AST]], + kwd_attrs: list[rowptr[AST]], kwd_patterns: list[rowptr[AST]])""" + cls: rowptr[AST] + patterns: rowptr[list[rowptr[AST]]] + kwd_attrs: rowptr[list[rowptr[AST]]] + kwd_patterns: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - cls: AST | t.CPtr, - patterns: list[AST | t.CPtr] | t.CPtr, - kwd_attrs: list[AST | t.CPtr] | t.CPtr, - kwd_patterns: list[AST | t.CPtr] | t.CPtr): - ptr: MatchClass | t.CPtr = pool.alloc(MatchClass.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + cls: rowptr[AST], + patterns: rowptr[list[rowptr[AST]]], + kwd_attrs: rowptr[list[rowptr[AST]]], + kwd_patterns: rowptr[list[rowptr[AST]]]): + ptr: rowptr[MatchClass] = pool.alloc(MatchClass.__sizeof__()) if ptr: string.memset(ptr, 0, MatchClass.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - cls: AST | t.CPtr, - patterns: list[AST | t.CPtr] | t.CPtr, - kwd_attrs: list[AST | t.CPtr] | t.CPtr, - kwd_patterns: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + cls: rowptr[AST], + patterns: rowptr[list[rowptr[AST]]], + kwd_attrs: rowptr[list[rowptr[AST]]], + kwd_patterns: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.cls = cls self.patterns = patterns @@ -236,13 +236,13 @@ class MatchClass(AST): _set_parent_list(kwd_attrs, self) _set_parent_list(kwd_patterns, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchClass def type_name(self) -> str: return "MatchClass" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchClass(cls=") if self.cls is not None: @@ -265,23 +265,23 @@ class MatchStar(AST): """MatchStar(name: str)""" name: str - def __new__(self, pool: memhub.MemManager | t.CPtr, name: str): - ptr: MatchStar | t.CPtr = pool.alloc(MatchStar.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], name: str): + ptr: rowptr[MatchStar] = pool.alloc(MatchStar.__sizeof__()) if ptr: string.memset(ptr, 0, MatchStar.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, name: str): + def __init__(self, pool: rowptr[memhub.MemManager], name: str): _init_ast(self, pool, 0, 0) self.name = _copy_str(pool, name) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchStar def type_name(self) -> str: return "MatchStar" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchStar(name='") pos = _emit_str(buf, size, pos, self.name) @@ -295,29 +295,29 @@ class MatchStar(AST): class MatchAs(AST): """MatchAs(pattern: AST, name: str)""" - pattern: AST | t.CPtr + pattern: rowptr[AST] name: str - def __new__(self, pool: memhub.MemManager | t.CPtr, - pattern: AST | t.CPtr, name: str): - ptr: MatchAs | t.CPtr = pool.alloc(MatchAs.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + pattern: rowptr[AST], name: str): + ptr: rowptr[MatchAs] = pool.alloc(MatchAs.__sizeof__()) if ptr: string.memset(ptr, 0, MatchAs.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - pattern: AST | t.CPtr, name: str): + def __init__(self, pool: rowptr[memhub.MemManager], + pattern: rowptr[AST], name: str): _init_ast(self, pool, 0, 0) self.pattern = pattern self.name = _copy_str(pool, name) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchAs def type_name(self) -> str: return "MatchAs" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchAs(pattern=") if self.pattern is not None: @@ -333,29 +333,29 @@ class MatchAs(AST): # ============================================================ class MatchOr(AST): - """MatchOr(patterns: list[AST | t.CPtr])""" - patterns: list[AST | t.CPtr] | t.CPtr + """MatchOr(patterns: list[rowptr[AST]])""" + patterns: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - patterns: list[AST | t.CPtr] | t.CPtr): - ptr: MatchOr | t.CPtr = pool.alloc(MatchOr.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + patterns: rowptr[list[rowptr[AST]]]): + ptr: rowptr[MatchOr] = pool.alloc(MatchOr.__sizeof__()) if ptr: string.memset(ptr, 0, MatchOr.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - patterns: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + patterns: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.patterns = patterns _set_parent_list(patterns, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.MatchOr def type_name(self) -> str: return "MatchOr" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "MatchOr(patterns=") pos = _dump_list(self.patterns, buf, size, pos) diff --git a/ast/parser.vp b/ast/parser.vp index e6584ee..e65b559 100644 --- a/ast/parser.vp +++ b/ast/parser.vp @@ -10,7 +10,7 @@ from .base import ( _set_pos, _binop_from_op, _augop_from_op, _cmpop_from_op, _copy_str, _inherit_pos, _init_ast, CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE, CONST_CHAR, - FLAG_IS_ASYNC, FLAG_IS_EXTERN, FLAG_IS_EXPORT, + FLAG_IS_ASYNC, FLAG_IS_EXTERN, FLAG_IS_EXPORT, FLAG_IS_DEFINE, ) from .exprs import ( BoolOp, BinOp, UnaryOp, Lambda, IfExp, Dict, Set, @@ -39,26 +39,26 @@ from .lexer import Lexer, _lexer_init, tokenize, new_lexer # Parser State # ============================================================ class Parser: - tokens: Token | t.CPtr # token linked list head - cur: Token | t.CPtr # current token - pool: memhub.MemManager | t.CPtr # memory pool - error_count: t.CInt # error count - pending_decorators: list[AST | t.CPtr] | t.CPtr # pending decorators list + tokens: rowptr[Token] # token linked list head + cur: rowptr[Token] # current token + pool: rowptr[memhub.MemManager] # memory pool + error_count: int # error count + pending_decorators: rowptr[list[rowptr[AST]]] # pending decorators list - def __new__(self, pool: memhub.MemManager | t.CPtr): - ptr: Parser | t.CPtr = pool.alloc(Parser.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager]): + ptr: rowptr[Parser] = pool.alloc(Parser.__sizeof__()) if ptr: string.memset(ptr, 0, Parser.__sizeof__()) return ptr -def new_parser(pool: memhub.MemManager | t.CPtr) -> Parser | t.CPtr: +def new_parser(pool: rowptr[memhub.MemManager]) -> rowptr[Parser]: """Allocate from the pool and return the Parser (cross-module safe wrapper)""" return Parser(pool) -def _parser_init(ps: Parser | t.CPtr, tokens: Token | t.CPtr, - pool: memhub.MemManager | t.CPtr): +def _parser_init(ps: rowptr[Parser], tokens: rowptr[Token], + pool: rowptr[memhub.MemManager]): if ps is None: return ps.tokens = tokens ps.cur = tokens @@ -71,29 +71,29 @@ def _parser_init(ps: Parser | t.CPtr, tokens: Token | t.CPtr, # Token Navigation Helpers # ============================================================ -def _advance(ps: Parser | t.CPtr): +def _advance(ps: rowptr[Parser]): """Advance to the next token""" if ps.cur is None: return if ps.cur.next is not None: ps.cur = ps.cur.next -def _cur_type(ps: Parser | t.CPtr) -> t.CInt: +def _cur_type(ps: rowptr[Parser]) -> int: if ps.cur is None: return TokenType.EndMarker return ps.cur.type -def _cur_op(ps: Parser | t.CPtr) -> t.CInt: +def _cur_op(ps: rowptr[Parser]) -> int: if ps.cur is None: return 0 return ps.cur.op_subtype -def _cur_kw(ps: Parser | t.CPtr) -> t.CInt: +def _cur_kw(ps: rowptr[Parser]) -> int: if ps.cur is None: return 0 return ps.cur.kw_subtype -def _is_funcdef_kw(ps: Parser | t.CPtr, kw: t.CInt) -> int: +def _is_funcdef_kw(ps: rowptr[Parser], kw: int) -> int: """判断当前 token 是否为函数定义关键字(def 及其别名 fn/fun/func/function, 以及 extern/export 声明关键字) @@ -102,21 +102,21 @@ def _is_funcdef_kw(ps: Parser | t.CPtr, kw: t.CInt) -> int: 判定为函数定义。extern 还允许 'extern def A(...)' 形式(下一个是 def), export 同样允许 'export def A(...)' 形式。 否则按普通标识符处理,兼容既有代码把 func 用作 - 字段/参数名(如 AST 节点 func 字段、Call.func 注解 `func: AST | t.CPtr`)。 + 字段/参数名(如 AST 节点 func 字段、Call.func 注解 `func: rowptr[AST]`)。 """ if kw == Keyword.Def: return 1 if kw == Keyword.Extern or kw == Keyword.Export: # extern/export def A(...) 或 extern/export A(...) # (extern/export 后是 def 或 Name+'(/'[') - nxt: Token | t.CPtr = ps.cur.next + nxt: rowptr[Token] = ps.cur.next if nxt is None: return 0 if nxt.kw_subtype == Keyword.Def: return 1 if nxt.type != TokenType.Name: return 0 - nxt2: Token | t.CPtr = nxt.next + nxt2: rowptr[Token] = nxt.next if nxt2 is None: return 0 if nxt2.type == TokenType.Op \ @@ -124,14 +124,16 @@ def _is_funcdef_kw(ps: Parser | t.CPtr, kw: t.CInt) -> int: return 1 return 0 if kw == Keyword.Fn or kw == Keyword.Fun \ - or kw == Keyword.Func or kw == Keyword.Function: + or kw == Keyword.Func or kw == Keyword.Function \ + or kw == Keyword.Define: # 软关键字 lookahead: 下个是 Name,再下个是 '(' 或 '[T...]' 泛型参数(PEP 695) - nxt: Token | t.CPtr = ps.cur.next + # (define 宏函数与 def 语义一致,返回注解自动追加 t.CDefine) + nxt: rowptr[Token] = ps.cur.next if nxt is None: return 0 if nxt.type != TokenType.Name: return 0 - nxt2: Token | t.CPtr = nxt.next + nxt2: rowptr[Token] = nxt.next if nxt2 is None: return 0 if nxt2.type == TokenType.Op \ @@ -141,15 +143,15 @@ def _is_funcdef_kw(ps: Parser | t.CPtr, kw: t.CInt) -> int: return 0 -def _is_match_stmt(ps: Parser | t.CPtr) -> int: +def _is_match_stmt(ps: rowptr[Parser]) -> int: """match 是软关键字(CPython 3.10+):lookahead 判断是否为 match 语句 - match 后直接跟 ':'(变量注解,如 lexer.vp 的 `match: t.CInt = 1`)、 + match 后直接跟 ':'(变量注解,如 lexer.vp 的 `match: int = 1`)、 '='(赋值,如 `match = 0`)、换行/文件尾 → 按普通标识符; 否则扫描至行尾,在括号深度 0 处出现 ':' → match 语句(subject 后必须冒号)。 case/type 同理为软关键字(case 仅在 match 套件内消费,type 无语句分发)。 """ - nxt: Token | t.CPtr = ps.cur.next + nxt: rowptr[Token] = ps.cur.next if nxt is None: return 0 if nxt.type == TokenType.NewLine or nxt.type == TokenType.EndMarker: @@ -159,13 +161,13 @@ def _is_match_stmt(ps: Parser | t.CPtr) -> int: return 0 if nxt.op_subtype == TokOp.Equal: return 0 - walk: Token | t.CPtr = nxt - depth: t.CInt = 0 + walk: rowptr[Token] = nxt + depth: int = 0 while walk is not None: if walk.type == TokenType.NewLine or walk.type == TokenType.EndMarker: return 0 if walk.type == TokenType.Op: - wop: t.CInt = walk.op_subtype + wop: int = walk.op_subtype if wop == TokOp.LPar or wop == TokOp.Lsqb or wop == TokOp.LBrace: depth += 1 elif wop == TokOp.RPar or wop == TokOp.Rsqb or wop == TokOp.RBrace: @@ -178,12 +180,12 @@ def _is_match_stmt(ps: Parser | t.CPtr) -> int: # 解析错误位置与消息(fail-fast 仿 Python SyntaxError 报告,首次错误记录) -_g_parse_err_line: t.CInt = 0 -_g_parse_err_col: t.CInt = 0 +_g_parse_err_line: int = 0 +_g_parse_err_col: int = 0 _g_parse_err_msg: str = None -def _record_parse_err(ps: Parser | t.CPtr): +def _record_parse_err(ps: rowptr[Parser]): """记录首个解析错误的位置与消息(只记录第一次,后续错误不覆盖)""" global _g_parse_err_line, _g_parse_err_col, _g_parse_err_msg if _g_parse_err_line != 0: @@ -202,12 +204,12 @@ def _record_parse_err(ps: Parser | t.CPtr): _g_parse_err_msg = err_s -def get_parse_err_line() -> t.CInt: +def get_parse_err_line() -> int: """获取最近一次解析错误的行号(0=无错误)""" return _g_parse_err_line -def get_parse_err_col() -> t.CInt: +def get_parse_err_col() -> int: """获取最近一次解析错误的列号(0=无错误)""" return _g_parse_err_col @@ -217,28 +219,28 @@ def get_parse_err_msg() -> str: return _g_parse_err_msg -def _cur_str(ps: Parser | t.CPtr) -> str: +def _cur_str(ps: rowptr[Parser]) -> str: if ps.cur is None: return None return ps.cur.str_val -def _cur_lineno(ps: Parser | t.CPtr) -> t.CInt: +def _cur_lineno(ps: rowptr[Parser]) -> int: if ps.cur is None: return 0 return ps.cur.lineno -def _cur_col(ps: Parser | t.CPtr) -> t.CInt: +def _cur_col(ps: rowptr[Parser]) -> int: if ps.cur is None: return 0 return ps.cur.col_offset -def _skip_nl(ps: Parser | t.CPtr): +def _skip_nl(ps: rowptr[Parser]): """Skip TokenType.Nl token""" while ps.cur is not None and ps.cur.type == TokenType.Nl: ps.cur = ps.cur.next -def _skip_nls_and_newlines(ps: Parser | t.CPtr): +def _skip_nls_and_newlines(ps: rowptr[Parser]): """Skip TokenType.Nl and TokenType.NewLine (used for line continuation)""" while ps.cur is not None: if ps.cur.type == TokenType.Nl or ps.cur.type == TokenType.NewLine: @@ -247,7 +249,7 @@ def _skip_nls_and_newlines(ps: Parser | t.CPtr): break -def _expect_type(ps: Parser | t.CPtr, ttype: t.CInt) -> t.CInt: +def _expect_type(ps: rowptr[Parser], ttype: int) -> int: """Expect the current token to be of the specified type, advance and return 1, otherwise return 0""" if _cur_type(ps) == ttype: _advance(ps) @@ -257,7 +259,7 @@ def _expect_type(ps: Parser | t.CPtr, ttype: t.CInt) -> t.CInt: return 0 -def _expect_op(ps: Parser | t.CPtr, op_id: t.CInt) -> t.CInt: +def _expect_op(ps: rowptr[Parser], op_id: int) -> int: """Expecting the current one to be some operator""" if _cur_type(ps) == TokenType.Op and _cur_op(ps) == op_id: _advance(ps) @@ -267,14 +269,14 @@ def _expect_op(ps: Parser | t.CPtr, op_id: t.CInt) -> t.CInt: return 0 -def _match_op(ps: Parser | t.CPtr, op_id: t.CInt) -> t.CInt: +def _match_op(ps: rowptr[Parser], op_id: int) -> int: """Check but not consume the current token""" if _cur_type(ps) == TokenType.Op and _cur_op(ps) == op_id: return 1 return 0 -def _accept_op(ps: Parser | t.CPtr, op_id: t.CInt) -> t.CInt: +def _accept_op(ps: rowptr[Parser], op_id: int) -> int: """If match, consume and return 1""" if _match_op(ps, op_id): _advance(ps) @@ -286,15 +288,15 @@ def _accept_op(ps: Parser | t.CPtr, op_id: t.CInt) -> t.CInt: # Constant Construction Helper (New API: Constant directly accepts lineno/col) # ============================================================ -def _new_const_int(pool: memhub.MemManager | t.CPtr, val: t.CInt64T, - lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _new_const_int(pool: rowptr[memhub.MemManager], val: int64, + lineno: int, col: int) -> rowptr[AST]: return Constant(pool, CONST_INT, val, 0.0, None, lineno, col) -def _new_const_float(pool: memhub.MemManager | t.CPtr, val: t.CDouble, - lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _new_const_float(pool: rowptr[memhub.MemManager], val: double, + lineno: int, col: int) -> rowptr[AST]: global _g_dbg_pts, _g_dbg_vals, _g_dbg_cnt - new_c: Constant | t.CPtr = Constant(pool, CONST_FLOAT, 0, val, None, lineno, col) + new_c: rowptr[Constant] = Constant(pool, CONST_FLOAT, 0, val, None, lineno, col) # 把数字文本存到 str_val(stdlib 分配,绕开 pool 对 float_val 字段的覆写) # REG-SRC 用 string.atof(str_val) 恢复原始值 lit_txt: str = stdlib.malloc(64) @@ -310,21 +312,21 @@ def _new_const_float(pool: memhub.MemManager | t.CPtr, val: t.CDouble, elif _g_dbg_cnt >= 4096: _g_dbg_cnt = 0 if _g_dbg_pts is not None and _g_dbg_vals is not None: - _g_dbg_pts[_g_dbg_cnt] = t.CUInt64T(new_c) + _g_dbg_pts[_g_dbg_cnt] = uint64(new_c) _g_dbg_vals[_g_dbg_cnt] = val _g_dbg_cnt += 1 return new_c # 浮点节点构造值表(stdlib 分配,避免污染 pool) -_g_dbg_pts: t.CUInt64T | t.CPtr = None -_g_dbg_vals: t.CDouble | t.CPtr = None +_g_dbg_pts: rowptr[uint64] = None +_g_dbg_vals: rowptr[double] = None _g_dbg_cnt: int = 0 # 最近一次 _dbg_lookup_lit_val 是否命中 _g_dbg_lit_found: int = 0 -def _dbg_lookup_lit_val(ptr: t.CUInt64T) -> double: +def _dbg_lookup_lit_val(ptr: uint64) -> double: """查浮点节点构造值表:返回 ptr 节点的原始构造值(未命中返回 0 并置 found=0) 用于绕开 pool 分配对 AST float_val 字段的覆写(构造时值正确,读取时可能被覆写)。 @@ -347,11 +349,11 @@ def _dbg_lit_found() -> int: return _g_dbg_lit_found -def _new_const_str(pool: memhub.MemManager | t.CPtr, val: str, - lineno: t.CInt, col: t.CInt, - is_dquote: t.CInt = 1, - is_triple: t.CInt = 0, - is_char: t.CInt = 0) -> AST | t.CPtr: +def _new_const_str(pool: rowptr[memhub.MemManager], val: str, + lineno: int, col: int, + is_dquote: int = 1, + is_triple: int = 0, + is_char: int = 0) -> rowptr[AST]: """Create a string/character constant node is_dquote: 0 = single quote, non-0 = double quote (default double quote) @@ -369,19 +371,19 @@ def _new_const_str(pool: memhub.MemManager | t.CPtr, val: str, if is_dquote == 0 and is_triple == 0 and is_char != 0: # Single quote # Single character → CONST_CHAR, int_val stores the character's ASCII value # val[0] is a legal value of 0 even if it's NUL - ch_val: t.CInt64T = val[0] + ch_val: int64 = val[0] return Constant(pool, CONST_CHAR, ch_val, 0.0, val, lineno, col) # Other situations → CONST_STR return Constant(pool, CONST_STR, 0, 0.0, val, lineno, col) -def _new_const_bool(pool: memhub.MemManager | t.CPtr, val: t.CInt, - lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _new_const_bool(pool: rowptr[memhub.MemManager], val: int, + lineno: int, col: int) -> rowptr[AST]: return Constant(pool, CONST_BOOL, val, 0.0, None, lineno, col) -def _new_const_none(pool: memhub.MemManager | t.CPtr, - lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _new_const_none(pool: rowptr[memhub.MemManager], + lineno: int, col: int) -> rowptr[AST]: return Constant(pool, CONST_NONE, 0, 0.0, None, lineno, col) @@ -389,52 +391,52 @@ def _new_const_none(pool: memhub.MemManager | t.CPtr, # ctx Helper (Recursive Fixing Store Context) # ============================================================ -def _set_ctx(node: AST | t.CPtr, ctx: t.CInt): +def _set_ctx(node: rowptr[AST], ctx: int): """Set ctx field of node (based on kind conversion)""" if node is None: return - k: t.CInt = node.kind() + k: int = node.kind() if k == ASTKind.Name: - nm: Name | t.CPtr = (Name | t.CPtr)(node) + nm: rowptr[Name] = (rowptr[Name])(node) nm.ctx = ctx elif k == ASTKind.Attribute: - at: Attribute | t.CPtr = (Attribute | t.CPtr)(node) + at: rowptr[Attribute] = (rowptr[Attribute])(node) at.ctx = ctx elif k == ASTKind.Subscript: - sb: Subscript | t.CPtr = (Subscript | t.CPtr)(node) + sb: rowptr[Subscript] = (rowptr[Subscript])(node) sb.ctx = ctx elif k == ASTKind.Tuple: - tp: Tuple | t.CPtr = (Tuple | t.CPtr)(node) + tp: rowptr[Tuple] = (rowptr[Tuple])(node) tp.ctx = ctx elif k == ASTKind.List: - ls: List | t.CPtr = (List | t.CPtr)(node) + ls: rowptr[List] = (rowptr[List])(node) ls.ctx = ctx elif k == ASTKind.Starred: - st: Starred | t.CPtr = (Starred | t.CPtr)(node) + st: rowptr[Starred] = (rowptr[Starred])(node) st.ctx = ctx -def _fix_store_ctx(node: AST | t.CPtr): +def _fix_store_ctx(node: rowptr[AST]): """Fix ctx of store targets to be Store""" if node is None: return _set_ctx(node, ASTCtx.Store) - k: t.CInt = node.kind() + k: int = node.kind() if k == ASTKind.Tuple or k == ASTKind.List: - tp_elts: list[AST | t.CPtr] | t.CPtr = None + tp_elts: rowptr[list[rowptr[AST]]] = None if k == ASTKind.Tuple: - tp: Tuple | t.CPtr = (Tuple | t.CPtr)(node) + tp: rowptr[Tuple] = (rowptr[Tuple])(node) tp_elts = tp.elts else: - ls: List | t.CPtr = (List | t.CPtr)(node) + ls: rowptr[List] = (rowptr[List])(node) tp_elts = ls.elts if tp_elts is not None: n: t.CSizeT = tp_elts.__len__() i: t.CSizeT = 0 while i < n: - cur: AST | t.CPtr = tp_elts.get(i) + cur: rowptr[AST] = tp_elts.get(i) _fix_store_ctx(cur) i += 1 elif k == ASTKind.Starred: - st2: Starred | t.CPtr = (Starred | t.CPtr)(node) + st2: rowptr[Starred] = (rowptr[Starred])(node) _fix_store_ctx(st2.value) @@ -442,39 +444,39 @@ def _fix_store_ctx(node: AST | t.CPtr): # Expression Parser # ============================================================ -def _parse_expr(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_expr(ps: rowptr[Parser]) -> rowptr[AST]: """expr: yield_expr | namedexpr_test""" if _cur_kw(ps) == Keyword.Yield: return _parse_yield(ps) return _parse_namedexpr(ps) -def _parse_namedexpr(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_namedexpr(ps: rowptr[Parser]) -> rowptr[AST]: """namedexpr_test: test [':=' test]""" - left: AST | t.CPtr = _parse_test(ps) + left: rowptr[AST] = _parse_test(ps) if left is None: return None if _match_op(ps, TokOp.ColonEq): _advance(ps) - right: AST | t.CPtr = _parse_test(ps) - node: AST | t.CPtr = NamedExpr(ps.pool, left, right) + right: rowptr[AST] = _parse_test(ps) + node: rowptr[AST] = NamedExpr(ps.pool, left, right) _set_pos(node, left.lineno, left.col_offset, 0, 0) return node return left -def _parse_test(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_test(ps: rowptr[Parser]) -> rowptr[AST]: """test: or_test ['if' or_test 'else' test] | lambdef""" if _cur_kw(ps) == Keyword.Lambda: return _parse_lambda(ps) - left: AST | t.CPtr = _parse_or_test(ps) + left: rowptr[AST] = _parse_or_test(ps) if left is None: return None if _cur_kw(ps) == Keyword.If: _advance(ps) - test: AST | t.CPtr = _parse_or_test(ps) + test: rowptr[AST] = _parse_or_test(ps) if _cur_kw(ps) == Keyword.Else: _advance(ps) - orelse: AST | t.CPtr = _parse_test(ps) - node: AST | t.CPtr = IfExp(ps.pool, test, left, orelse) + orelse: rowptr[AST] = _parse_test(ps) + node: rowptr[AST] = IfExp(ps.pool, test, left, orelse) _set_pos(node, left.lineno, left.col_offset, 0, 0) return node ps.error_count += 1 @@ -482,27 +484,27 @@ def _parse_test(ps: Parser | t.CPtr) -> AST | t.CPtr: return left -def _parse_lambda(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_lambda(ps: rowptr[Parser]) -> rowptr[AST]: """lambdef: 'lambda' [varargslist] ':' test""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # lambda - args: AST | t.CPtr = None + args: rowptr[AST] = None if not _match_op(ps, TokOp.Colon): args = _parse_varargslist(ps, 1) if not _expect_op(ps, TokOp.Colon): return None - body: AST | t.CPtr = _parse_test(ps) - node: AST | t.CPtr = Lambda(ps.pool, args, body) + body: rowptr[AST] = _parse_test(ps) + node: rowptr[AST] = Lambda(ps.pool, args, body) _set_pos(node, lineno, col, 0, 0) return node -def _parse_or_test(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_or_test(ps: rowptr[Parser]) -> rowptr[AST]: """or_test: and_test ('or' and_test)*""" - left: AST | t.CPtr = _parse_and_test(ps) + left: rowptr[AST] = _parse_and_test(ps) if left is None: return None - values: list[AST | t.CPtr] | t.CPtr = None + values: rowptr[list[rowptr[AST]]] = None while True: # 括号内行首 or((A\n or B))与行尾 or(A or\n B)都支持: # 每轮先 _skip_nl 再检查 or,否则 A or B\n or C 在 B 后停在 Nl 上 @@ -511,25 +513,25 @@ def _parse_or_test(ps: Parser | t.CPtr) -> AST | t.CPtr: if _cur_kw(ps) != Keyword.Or: break if values is None: - values = list[AST | t.CPtr](ps.pool, 8) + values = list[rowptr[AST]](ps.pool, 8) values.append(left) _advance(ps) _skip_nl(ps) # 括号内跨行: a or\n b - right: AST | t.CPtr = _parse_and_test(ps) + right: rowptr[AST] = _parse_and_test(ps) if right is None: break values.append(right) if values is not None: - node: AST | t.CPtr = BoolOp(ps.pool, OpKind.Or, values) + node: rowptr[AST] = BoolOp(ps.pool, OpKind.Or, values) _set_pos(node, left.lineno, left.col_offset, 0, 0) return node return left -def _parse_and_test(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_and_test(ps: rowptr[Parser]) -> rowptr[AST]: """and_test: not_test ('and' not_test)*""" - left: AST | t.CPtr = _parse_not_test(ps) + left: rowptr[AST] = _parse_not_test(ps) if left is None: return None - values: list[AST | t.CPtr] | t.CPtr = None + values: rowptr[list[rowptr[AST]]] = None while True: # 括号内行首 and((A\n and B))与行尾 and(A and\n B)都支持: # 每轮先 _skip_nl 再检查 and,否则 A and B\n and C 在 B 后停在 @@ -539,90 +541,90 @@ def _parse_and_test(ps: Parser | t.CPtr) -> AST | t.CPtr: if _cur_kw(ps) != Keyword.And: break if values is None: - values = list[AST | t.CPtr](ps.pool, 8) + values = list[rowptr[AST]](ps.pool, 8) values.append(left) _advance(ps) _skip_nl(ps) # 括号内跨行: a and\n b - right: AST | t.CPtr = _parse_not_test(ps) + right: rowptr[AST] = _parse_not_test(ps) if right is None: break values.append(right) if values is not None: - node: AST | t.CPtr = BoolOp(ps.pool, OpKind.And, values) + node: rowptr[AST] = BoolOp(ps.pool, OpKind.And, values) _set_pos(node, left.lineno, left.col_offset, 0, 0) return node return left -def _parse_not_test(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_not_test(ps: rowptr[Parser]) -> rowptr[AST]: """not_test: 'not' not_test | comparison""" if _cur_kw(ps) == Keyword.Not: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - operand: AST | t.CPtr = _parse_not_test(ps) - node: AST | t.CPtr = UnaryOp(ps.pool, OpKind.Not, operand) + operand: rowptr[AST] = _parse_not_test(ps) + node: rowptr[AST] = UnaryOp(ps.pool, OpKind.Not, operand) _set_pos(node, lineno, col, 0, 0) return node return _parse_comparison(ps) -def _parse_comparison(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_comparison(ps: rowptr[Parser]) -> rowptr[AST]: """comparison: bitor_expr (comp_op bitor_expr)* Single comparison design: a < b → Compare(left=a, op=Lt, right=b) Chained comparison a < b < c → BoolOp(And, [Compare(a,<,b), Compare(b,<,c)]) """ - left: AST | t.CPtr = _parse_bitor(ps) + left: rowptr[AST] = _parse_bitor(ps) if left is None: return None _skip_nl(ps) # 括号内行首比较运算符: (a\n < b) - op_id: t.CInt = _match_comp_op(ps) + op_id: int = _match_comp_op(ps) if op_id == OpKind.NoneOp: return left _advance_comp_op(ps) _skip_nl(ps) # 括号内跨行: a ==\n b - right: AST | t.CPtr = _parse_bitor(ps) + right: rowptr[AST] = _parse_bitor(ps) # Single comparison: construct ops and comparators list - ops: list[t.CInt] | t.CPtr = list[t.CInt](ps.pool, 8) + ops: rowptr[list[int]] = list[int](ps.pool, 8) ops.append(op_id) - comparators: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + comparators: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) comparators.append(right) - first_cmp: AST | t.CPtr = Compare(ps.pool, left, ops, comparators) + first_cmp: rowptr[AST] = Compare(ps.pool, left, ops, comparators) _set_pos(first_cmp, left.lineno, left.col_offset, 0, 0) # Check chained comparison _skip_nl(ps) # 括号内行首链式比较: (a < b\n < c) - next_op: t.CInt = _match_comp_op(ps) + next_op: int = _match_comp_op(ps) if next_op == OpKind.NoneOp: return first_cmp # Single comparison with chained conditions: a < b < c → BoolOp(And, [Compare(a,<,b), Compare(b,<,c), ...]) - values: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + values: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) values.append(first_cmp) - cur_left: AST | t.CPtr = right + cur_left: rowptr[AST] = right while next_op != OpKind.NoneOp: _advance_comp_op(ps) _skip_nl(ps) # 括号内跨行链式比较 - cur_right: AST | t.CPtr = _parse_bitor(ps) - ops2: list[t.CInt] | t.CPtr = list[t.CInt](ps.pool, 8) + cur_right: rowptr[AST] = _parse_bitor(ps) + ops2: rowptr[list[int]] = list[int](ps.pool, 8) ops2.append(next_op) - comparators2: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + comparators2: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) comparators2.append(cur_right) - cmp: AST | t.CPtr = Compare(ps.pool, cur_left, ops2, comparators2) + cmp: rowptr[AST] = Compare(ps.pool, cur_left, ops2, comparators2) _set_pos(cmp, cur_left.lineno, cur_left.col_offset, 0, 0) values.append(cmp) cur_left = cur_right _skip_nl(ps) # 括号内行首链式比较: (a < b\n < c) next_op = _match_comp_op(ps) - node: AST | t.CPtr = BoolOp(ps.pool, OpKind.And, values) + node: rowptr[AST] = BoolOp(ps.pool, OpKind.And, values) _set_pos(node, left.lineno, left.col_offset, 0, 0) return node -def _match_comp_op(ps: Parser | t.CPtr) -> t.CInt: +def _match_comp_op(ps: rowptr[Parser]) -> int: """Check if the current one is a comparison operator, return OP_* or OpKind.NoneOp""" if _cur_type(ps) == TokenType.Op: - op_id: t.CInt = _cur_op(ps) + op_id: int = _cur_op(ps) if op_id == TokOp.EqEq: return OpKind.Eq if op_id == TokOp.ExclaimEq: return OpKind.Ne if op_id == TokOp.Less: return OpKind.Lt @@ -641,7 +643,7 @@ def _match_comp_op(ps: Parser | t.CPtr) -> t.CInt: return OpKind.NoneOp -def _advance_comp_op(ps: Parser | t.CPtr): +def _advance_comp_op(ps: rowptr[Parser]): """Consume comparison operator token""" if _cur_type(ps) == TokenType.Op: _advance(ps) @@ -660,8 +662,8 @@ def _advance_comp_op(ps: Parser | t.CPtr): _advance(ps) -def _parse_bitor(ps: Parser | t.CPtr) -> AST | t.CPtr: - left: AST | t.CPtr = _parse_bitxor(ps) +def _parse_bitor(ps: rowptr[Parser]) -> rowptr[AST]: + left: rowptr[AST] = _parse_bitxor(ps) if left is None: return None while True: _skip_nl(ps) # 括号内行首 '|': (a\n | b) @@ -669,15 +671,15 @@ def _parse_bitor(ps: Parser | t.CPtr) -> AST | t.CPtr: break _advance(ps) _skip_nl(ps) # 括号内跨行: a |\n b - right: AST | t.CPtr = _parse_bitxor(ps) - node: AST | t.CPtr = BinOp(ps.pool, left, OpKind.BitOr, right) + right: rowptr[AST] = _parse_bitxor(ps) + node: rowptr[AST] = BinOp(ps.pool, left, OpKind.BitOr, right) _set_pos(node, left.lineno, left.col_offset, 0, 0) left = node return left -def _parse_bitxor(ps: Parser | t.CPtr) -> AST | t.CPtr: - left: AST | t.CPtr = _parse_bitand(ps) +def _parse_bitxor(ps: rowptr[Parser]) -> rowptr[AST]: + left: rowptr[AST] = _parse_bitand(ps) if left is None: return None while True: _skip_nl(ps) # 括号内行首 '^': (a\n ^ b) @@ -685,15 +687,15 @@ def _parse_bitxor(ps: Parser | t.CPtr) -> AST | t.CPtr: break _advance(ps) _skip_nl(ps) # 括号内跨行: a ^\n b - right: AST | t.CPtr = _parse_bitand(ps) - node: AST | t.CPtr = BinOp(ps.pool, left, OpKind.BitXor, right) + right: rowptr[AST] = _parse_bitand(ps) + node: rowptr[AST] = BinOp(ps.pool, left, OpKind.BitXor, right) _set_pos(node, left.lineno, left.col_offset, 0, 0) left = node return left -def _parse_bitand(ps: Parser | t.CPtr) -> AST | t.CPtr: - left: AST | t.CPtr = _parse_shift(ps) +def _parse_bitand(ps: rowptr[Parser]) -> rowptr[AST]: + left: rowptr[AST] = _parse_shift(ps) if left is None: return None while True: _skip_nl(ps) # 括号内行首 '&': (a\n & b) @@ -701,59 +703,59 @@ def _parse_bitand(ps: Parser | t.CPtr) -> AST | t.CPtr: break _advance(ps) _skip_nl(ps) # 括号内跨行: a &\n b - right: AST | t.CPtr = _parse_shift(ps) - node: AST | t.CPtr = BinOp(ps.pool, left, OpKind.BitAnd, right) + right: rowptr[AST] = _parse_shift(ps) + node: rowptr[AST] = BinOp(ps.pool, left, OpKind.BitAnd, right) _set_pos(node, left.lineno, left.col_offset, 0, 0) left = node return left -def _parse_shift(ps: Parser | t.CPtr) -> AST | t.CPtr: - left: AST | t.CPtr = _parse_arith(ps) +def _parse_shift(ps: rowptr[Parser]) -> rowptr[AST]: + left: rowptr[AST] = _parse_arith(ps) if left is None: return None while True: _skip_nl(ps) # 括号内行首 '<<'/'>>': (a\n << b) if _match_op(ps, TokOp.LtLt) == 0 and _match_op(ps, TokOp.GtGt) == 0: break - op_token: t.CInt = _cur_op(ps) + op_token: int = _cur_op(ps) _advance(ps) _skip_nl(ps) # 括号内跨行: a <<\n b - right: AST | t.CPtr = _parse_arith(ps) - ast_op: t.CInt = OpKind.LShift + right: rowptr[AST] = _parse_arith(ps) + ast_op: int = OpKind.LShift if op_token == TokOp.GtGt: ast_op = OpKind.RShift - node: AST | t.CPtr = BinOp(ps.pool, left, ast_op, right) + node: rowptr[AST] = BinOp(ps.pool, left, ast_op, right) _set_pos(node, left.lineno, left.col_offset, 0, 0) left = node return left -def _parse_arith(ps: Parser | t.CPtr) -> AST | t.CPtr: - left: AST | t.CPtr = _parse_term(ps) +def _parse_arith(ps: rowptr[Parser]) -> rowptr[AST]: + left: rowptr[AST] = _parse_term(ps) if left is None: return None while True: _skip_nl(ps) # 括号内行首 '+'/'-': (a\n + b) if _match_op(ps, TokOp.Plus) == 0 and _match_op(ps, TokOp.Minus) == 0: break - op_token: t.CInt = _cur_op(ps) + op_token: int = _cur_op(ps) _advance(ps) _skip_nl(ps) # 括号内跨行: a +\n b - right: AST | t.CPtr = _parse_term(ps) - ast_op: t.CInt = OpKind.Add + right: rowptr[AST] = _parse_term(ps) + ast_op: int = OpKind.Add if op_token == TokOp.Minus: ast_op = OpKind.Sub - node: AST | t.CPtr = BinOp(ps.pool, left, ast_op, right) + node: rowptr[AST] = BinOp(ps.pool, left, ast_op, right) _set_pos(node, left.lineno, left.col_offset, 0, 0) left = node return left -def _parse_term(ps: Parser | t.CPtr) -> AST | t.CPtr: - left: AST | t.CPtr = _parse_factor(ps) +def _parse_term(ps: rowptr[Parser]) -> rowptr[AST]: + left: rowptr[AST] = _parse_factor(ps) if left is None: return None while True: _skip_nl(ps) # 括号内行首 '*'/'/'/'//'/'%'/'@': (a\n * b) - op_token: t.CInt = 0 + op_token: int = 0 if _match_op(ps, TokOp.Star): op_token = TokOp.Star elif _match_op(ps, TokOp.Slash): op_token = TokOp.Slash elif _match_op(ps, TokOp.DSlash): op_token = TokOp.DSlash @@ -762,57 +764,62 @@ def _parse_term(ps: Parser | t.CPtr) -> AST | t.CPtr: if op_token == 0: break _advance(ps) _skip_nl(ps) # 括号内跨行: a *\n b - right: AST | t.CPtr = _parse_factor(ps) - ast_op: t.CInt = _binop_from_op(op_token) - node: AST | t.CPtr = BinOp(ps.pool, left, ast_op, right) + right: rowptr[AST] = _parse_factor(ps) + ast_op: int = _binop_from_op(op_token) + node: rowptr[AST] = BinOp(ps.pool, left, ast_op, right) _set_pos(node, left.lineno, left.col_offset, 0, 0) left = node return left -def _parse_factor(ps: Parser | t.CPtr) -> AST | t.CPtr: - """factor: '+' factor | '-' factor | '~' factor | power""" - if _match_op(ps, TokOp.Plus) or _match_op(ps, TokOp.Minus) or _match_op(ps, TokOp.Tilde): - op_token: t.CInt = _cur_op(ps) - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_factor(ps: rowptr[Parser]) -> rowptr[AST]: + """factor: '+' factor | '-' factor | '~' factor | '*' factor | '&' factor | power""" + if (_match_op(ps, TokOp.Plus) or _match_op(ps, TokOp.Minus) or _match_op(ps, TokOp.Tilde) + or _match_op(ps, TokOp.Star) or _match_op(ps, TokOp.Amp)): + op_token: int = _cur_op(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - operand: AST | t.CPtr = _parse_factor(ps) - ast_op: t.CInt = OpKind.UAdd + operand: rowptr[AST] = _parse_factor(ps) + ast_op: int = OpKind.UAdd if op_token == TokOp.Minus: ast_op = OpKind.USub elif op_token == TokOp.Tilde: ast_op = OpKind.Invert - node: AST | t.CPtr = UnaryOp(ps.pool, ast_op, operand) + elif op_token == TokOp.Star: + ast_op = OpKind.Deref + elif op_token == TokOp.Amp: + ast_op = OpKind.AddrOf + node: rowptr[AST] = UnaryOp(ps.pool, ast_op, operand) _set_pos(node, lineno, col, 0, 0) return node return _parse_power(ps) -def _parse_power(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_power(ps: rowptr[Parser]) -> rowptr[AST]: """power: await_expr ['**' factor] | atom_expr ['**' factor]""" - base: AST | t.CPtr = _parse_atom_expr(ps) + base: rowptr[AST] = _parse_atom_expr(ps) if base is None: return None if _match_op(ps, TokOp.StarStar): _advance(ps) - exp: AST | t.CPtr = _parse_factor(ps) - node: AST | t.CPtr = BinOp(ps.pool, base, OpKind.Pow, exp) + exp: rowptr[AST] = _parse_factor(ps) + node: rowptr[AST] = BinOp(ps.pool, base, OpKind.Pow, exp) _set_pos(node, base.lineno, base.col_offset, 0, 0) return node return base -def _parse_atom_expr(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_atom_expr(ps: rowptr[Parser]) -> rowptr[AST]: """atom_expr: ['await'] atom trailer*""" if _cur_kw(ps) == Keyword.Await: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - inner: AST | t.CPtr = _parse_atom_expr(ps) - node: AST | t.CPtr = Await(ps.pool, inner) + inner: rowptr[AST] = _parse_atom_expr(ps) + node: rowptr[AST] = Await(ps.pool, inner) _set_pos(node, lineno, col, 0, 0) return node - base: AST | t.CPtr = _parse_atom(ps) + base: rowptr[AST] = _parse_atom(ps) if base is None: return None # trailer loop while True: @@ -822,10 +829,10 @@ def _parse_atom_expr(ps: Parser | t.CPtr) -> AST | t.CPtr: ps.error_count += 1 break attr_name: str = _cur_str(ps) - attr_lineno: t.CInt = _cur_lineno(ps) - attr_col: t.CInt = _cur_col(ps) + attr_lineno: int = _cur_lineno(ps) + attr_col: int = _cur_col(ps) _advance(ps) - ctx: t.CInt = ASTCtx.Load + ctx: int = ASTCtx.Load if _match_op(ps, TokOp.Equal): ctx = ASTCtx.Store elif _match_op(ps, TokOp.PlusEq) or _match_op(ps, TokOp.MinusEq): @@ -841,14 +848,14 @@ def _parse_atom_expr(ps: Parser | t.CPtr) -> AST | t.CPtr: return base -def _parse_call(ps: Parser | t.CPtr, func: AST | t.CPtr) -> AST | t.CPtr: +def _parse_call(ps: rowptr[Parser], func: rowptr[AST]) -> rowptr[AST]: """Parse function call trailer. Both args and keywords are lists.""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # ( _skip_nls_and_newlines(ps) # Skip the line break after '(' - args: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - keywords: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + args: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + keywords: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) if not _match_op(ps, TokOp.RPar): while True: @@ -856,8 +863,8 @@ def _parse_call(ps: Parser | t.CPtr, func: AST | t.CPtr) -> AST | t.CPtr: if _match_op(ps, TokOp.StarStar): _advance(ps) _skip_nls_and_newlines(ps) - val: AST | t.CPtr = _parse_expr(ps) - kw: AST | t.CPtr = KwNode(ps.pool, None, val) + val: rowptr[AST] = _parse_expr(ps) + kw: rowptr[AST] = KwNode(ps.pool, None, val) _set_pos(kw, _cur_lineno(ps), _cur_col(ps), 0, 0) keywords.append(kw) # *expr @@ -865,15 +872,15 @@ def _parse_call(ps: Parser | t.CPtr, func: AST | t.CPtr) -> AST | t.CPtr: _advance(ps) _skip_nls_and_newlines(ps) val = _parse_expr(ps) - star: AST | t.CPtr = Starred(ps.pool, val, ASTCtx.Load) + star: rowptr[AST] = Starred(ps.pool, val, ASTCtx.Load) _set_pos(star, val.lineno, val.col_offset, 0, 0) args.append(star) # keyword = expr elif _cur_type(ps) == TokenType.Name: if ps.cur.next is not None and ps.cur.next.type == TokenType.Op and ps.cur.next.op_subtype == TokOp.Equal: kw_name: str = _cur_str(ps) - kw_lineno: t.CInt = _cur_lineno(ps) - kw_col: t.CInt = _cur_col(ps) + kw_lineno: int = _cur_lineno(ps) + kw_col: int = _cur_col(ps) _advance(ps) # name _advance(ps) # = _skip_nls_and_newlines(ps) @@ -893,81 +900,81 @@ def _parse_call(ps: Parser | t.CPtr, func: AST | t.CPtr) -> AST | t.CPtr: _skip_nls_and_newlines(ps) # Skip the line break after the comma _skip_nls_and_newlines(ps) # Skip the line break before ')' _expect_op(ps, TokOp.RPar) - node: AST | t.CPtr = Call(ps.pool, func, args, keywords) + node: rowptr[AST] = Call(ps.pool, func, args, keywords) _set_pos(node, lineno, col, 0, 0) return node -def _parse_subscript(ps: Parser | t.CPtr, value: AST | t.CPtr) -> AST | t.CPtr: +def _parse_subscript(ps: rowptr[Parser], value: rowptr[AST]) -> rowptr[AST]: """Parse subscript trailer.""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # [ _skip_nl(ps) - slice_node: AST | t.CPtr = _parse_slice(ps) + slice_node: rowptr[AST] = _parse_slice(ps) _expect_op(ps, TokOp.Rsqb) - ctx: t.CInt = ASTCtx.Load + ctx: int = ASTCtx.Load if _match_op(ps, TokOp.Equal): ctx = ASTCtx.Store - node: AST | t.CPtr = Subscript(ps.pool, value, slice_node, ctx) + node: rowptr[AST] = Subscript(ps.pool, value, slice_node, ctx) _set_pos(node, lineno, col, 0, 0) return node -def _parse_slice(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_slice(ps: rowptr[Parser]) -> rowptr[AST]: """Parse slice: [expr] ':' [expr] [':' [expr]] | expr | expr, expr, ...""" - lower: AST | t.CPtr = None + lower: rowptr[AST] = None if not _match_op(ps, TokOp.Colon): lower = _parse_expr(ps) # Check if there’s a comma (tuple syntax: a[x, y, ...]) if _match_op(ps, TokOp.Comma): - elts: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + elts: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) if lower is not None: elts.append(lower) while _accept_op(ps, TokOp.Comma): if _match_op(ps, TokOp.Rsqb): break # Trailing comma - elem: AST | t.CPtr = _parse_expr(ps) + elem: rowptr[AST] = _parse_expr(ps) if elem is not None: elts.append(elem) - lineno: t.CInt = 0 + lineno: int = 0 if lower is not None: lineno = lower.lineno - node: AST | t.CPtr = Tuple(ps.pool, elts, ASTCtx.Load) + node: rowptr[AST] = Tuple(ps.pool, elts, ASTCtx.Load) _set_pos(node, lineno, 0, 0, 0) return node if _match_op(ps, TokOp.Colon): _advance(ps) - upper: AST | t.CPtr = None + upper: rowptr[AST] = None if not _match_op(ps, TokOp.Colon) and not _match_op(ps, TokOp.Rsqb): upper = _parse_expr(ps) - step: AST | t.CPtr = None + step: rowptr[AST] = None if _accept_op(ps, TokOp.Colon): if not _match_op(ps, TokOp.Rsqb): step = _parse_expr(ps) - lineno: t.CInt = 0 + lineno: int = 0 if lower is not None: lineno = lower.lineno elif upper is not None: lineno = upper.lineno else: lineno = _cur_lineno(ps) - node: AST | t.CPtr = Slice(ps.pool, lower, upper, step) + node: rowptr[AST] = Slice(ps.pool, lower, upper, step) _set_pos(node, lineno, 0, 0, 0) return node return lower -def _parse_atom(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_atom(ps: rowptr[Parser]) -> rowptr[AST]: """atom: the smallest unit of expression""" - ttype: t.CInt = _cur_type(ps) - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + ttype: int = _cur_type(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) if ttype == TokenType.Name: - kw: t.CInt = _cur_kw(ps) + kw: int = _cur_kw(ps) if kw == Keyword.True_: _advance(ps) return _new_const_bool(ps.pool, 1, lineno, col) @@ -979,12 +986,12 @@ def _parse_atom(ps: Parser | t.CPtr) -> AST | t.CPtr: return _new_const_none(ps.pool, lineno, col) name_str: str = _cur_str(ps) _advance(ps) - node: AST | t.CPtr = Name(ps.pool, name_str, ASTCtx.Load) + node: rowptr[AST] = Name(ps.pool, name_str, ASTCtx.Load) _set_pos(node, lineno, col, 0, 0) return node if ttype == TokenType.Number: - tok: Token | t.CPtr = ps.cur + tok: rowptr[Token] = ps.cur _advance(ps) if tok.is_float: return _new_const_float(ps.pool, tok.float_val, lineno, col) @@ -992,12 +999,12 @@ def _parse_atom(ps: Parser | t.CPtr) -> AST | t.CPtr: if ttype == TokenType.String: sval: str = _cur_str(ps) - is_fstr: t.CInt = ps.cur.kw_subtype & 4 - is_triple: t.CInt = ps.cur.kw_subtype & 8 - is_dquote: t.CInt = ps.cur.kw_subtype & 16 - is_char: t.CInt = ps.cur.kw_subtype & 32 + is_fstr: int = ps.cur.kw_subtype & 4 + is_triple: int = ps.cur.kw_subtype & 8 + is_dquote: int = ps.cur.kw_subtype & 16 + is_char: int = ps.cur.kw_subtype & 32 _advance(ps) - node: AST | t.CPtr + node: rowptr[AST] if is_fstr: node = _parse_fstring(ps, sval, lineno, col) else: @@ -1009,12 +1016,12 @@ def _parse_atom(ps: Parser | t.CPtr) -> AST | t.CPtr: if _cur_type(ps) != TokenType.String: break n_sval: str = _cur_str(ps) - n_fstr: t.CInt = ps.cur.kw_subtype & 4 - n_triple: t.CInt = ps.cur.kw_subtype & 8 - n_dquote: t.CInt = ps.cur.kw_subtype & 16 - n_char: t.CInt = ps.cur.kw_subtype & 32 + n_fstr: int = ps.cur.kw_subtype & 4 + n_triple: int = ps.cur.kw_subtype & 8 + n_dquote: int = ps.cur.kw_subtype & 16 + n_char: int = ps.cur.kw_subtype & 32 _advance(ps) - n_node: AST | t.CPtr + n_node: rowptr[AST] if n_fstr: n_node = _parse_fstring(ps, n_sval, lineno, col) else: @@ -1033,38 +1040,39 @@ def _parse_atom(ps: Parser | t.CPtr) -> AST | t.CPtr: if _match_op(ps, TokOp.LBrace): return _parse_brace(ps) + _record_parse_err(ps) ps.error_count += 1 return None -def _parse_paren(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_paren(ps: rowptr[Parser]) -> rowptr[AST]: """Parenthesis expressions: () | (expr) | (expr,) | (expr, ...) | (yield)""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # ( _skip_nl(ps) # Skip the line break after '(' (multi-line tuple) if _match_op(ps, TokOp.RPar): _advance(ps) # Empty tuple - empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - node: AST | t.CPtr = Tuple(ps.pool, empty, ASTCtx.Load) + empty: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + node: rowptr[AST] = Tuple(ps.pool, empty, ASTCtx.Load) _set_pos(node, lineno, col, 0, 0) return node # yield if _cur_kw(ps) == Keyword.Yield: - y: AST | t.CPtr = _parse_yield(ps) + y: rowptr[AST] = _parse_yield(ps) _expect_op(ps, TokOp.RPar) return y - first: AST | t.CPtr = _parse_expr(ps) + first: rowptr[AST] = _parse_expr(ps) if _match_op(ps, TokOp.Comma): # Tuple - elts: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + elts: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) elts.append(first) while _accept_op(ps, TokOp.Comma): _skip_nl(ps) if _match_op(ps, TokOp.RPar): break - e: AST | t.CPtr = _parse_expr(ps) + e: rowptr[AST] = _parse_expr(ps) elts.append(e) _skip_nl(ps) # 末元素无尾逗号时收尾(多行元组) _expect_op(ps, TokOp.RPar) @@ -1079,30 +1087,30 @@ def _parse_paren(ps: Parser | t.CPtr) -> AST | t.CPtr: return first -def _parse_list(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_list(ps: rowptr[Parser]) -> rowptr[AST]: """List expressions: [] | [expr_list] | [expr_list comp_for]""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # [ _skip_nl(ps) # Skip the line break after '[' (multi-line list) if _match_op(ps, TokOp.Rsqb): _advance(ps) - empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - node: AST | t.CPtr = List(ps.pool, empty, ASTCtx.Load) + empty: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + node: rowptr[AST] = List(ps.pool, empty, ASTCtx.Load) _set_pos(node, lineno, col, 0, 0) return node - first: AST | t.CPtr = _parse_expr(ps) + first: rowptr[AST] = _parse_expr(ps) if _cur_kw(ps) == Keyword.For: node = _parse_comprehension(ps, first, ASTKind.ListComp, lineno, col) _expect_op(ps, TokOp.Rsqb) return node - elts: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + elts: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) elts.append(first) while _accept_op(ps, TokOp.Comma): _skip_nl(ps) if _match_op(ps, TokOp.Rsqb): break - e: AST | t.CPtr = _parse_expr(ps) + e: rowptr[AST] = _parse_expr(ps) elts.append(e) _skip_nl(ps) # 末元素无尾逗号时收尾(base64.vp 多行列表) _expect_op(ps, TokOp.Rsqb) @@ -1111,42 +1119,42 @@ def _parse_list(ps: Parser | t.CPtr) -> AST | t.CPtr: return node -def _parse_brace(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_brace(ps: rowptr[Parser]) -> rowptr[AST]: """Brace expressions: {} | {set_items} | {dict_items} | {comp_for}""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # { _skip_nl(ps) # Skip the line break after '{' (multi-line dict) if _match_op(ps, TokOp.RBrace): _advance(ps) - empty_k: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - empty_v: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - node: AST | t.CPtr = Dict(ps.pool, empty_k, empty_v) + empty_k: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + empty_v: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + node: rowptr[AST] = Dict(ps.pool, empty_k, empty_v) _set_pos(node, lineno, col, 0, 0) return node - first: AST | t.CPtr = _parse_expr(ps) + first: rowptr[AST] = _parse_expr(ps) # dict: key: value if _match_op(ps, TokOp.Colon): _advance(ps) - val: AST | t.CPtr = _parse_expr(ps) + val: rowptr[AST] = _parse_expr(ps) if _cur_kw(ps) == Keyword.For: # dict comprehension - gens: list[AST | t.CPtr] | t.CPtr = _parse_comp_for(ps) + gens: rowptr[list[rowptr[AST]]] = _parse_comp_for(ps) node = DictComp(ps.pool, first, val, gens) _set_pos(node, lineno, col, 0, 0) _expect_op(ps, TokOp.RBrace) return node - keys: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - values: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + keys: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + values: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) keys.append(first) values.append(val) while _accept_op(ps, TokOp.Comma): _skip_nl(ps) if _match_op(ps, TokOp.RBrace): break - k: AST | t.CPtr = _parse_expr(ps) + k: rowptr[AST] = _parse_expr(ps) _expect_op(ps, TokOp.Colon) - v: AST | t.CPtr = _parse_expr(ps) + v: rowptr[AST] = _parse_expr(ps) keys.append(k) values.append(v) _skip_nl(ps) # 末元素无尾逗号时收尾 @@ -1159,13 +1167,13 @@ def _parse_brace(ps: Parser | t.CPtr) -> AST | t.CPtr: node = _parse_comprehension(ps, first, ASTKind.SetComp, lineno, col) _expect_op(ps, TokOp.RBrace) return node - elts: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + elts: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) elts.append(first) while _accept_op(ps, TokOp.Comma): _skip_nl(ps) # 括号内跨行集合字面量 if _match_op(ps, TokOp.RBrace): break - e: AST | t.CPtr = _parse_expr(ps) + e: rowptr[AST] = _parse_expr(ps) elts.append(e) _skip_nl(ps) # 末元素无尾逗号时收尾 _expect_op(ps, TokOp.RBrace) @@ -1178,28 +1186,28 @@ def _parse_brace(ps: Parser | t.CPtr) -> AST | t.CPtr: # f-string parsing # ============================================================ -def _parse_sub_expr(ps: Parser | t.CPtr, src: str) -> AST | t.CPtr: +def _parse_sub_expr(ps: rowptr[Parser], src: str) -> rowptr[AST]: """Create a sub-lexer and parser to parse expressions (used for {expr} inside f-strings)""" - pool: memhub.MemManager | t.CPtr = ps.pool - lx: Lexer | t.CPtr = new_lexer(pool) + pool: rowptr[memhub.MemManager] = ps.pool + lx: rowptr[Lexer] = new_lexer(pool) if lx is None: return None _lexer_init(lx, src, pool) - tokens: Token | t.CPtr = tokenize(lx) + tokens: rowptr[Token] = tokenize(lx) if tokens is None: return None - sub_ps: Parser | t.CPtr = new_parser(pool) + sub_ps: rowptr[Parser] = new_parser(pool) if sub_ps is None: return None _parser_init(sub_ps, tokens, pool) return _parse_test(sub_ps) -def _append_str_value(pool: memhub.MemManager | t.CPtr, - values: list[AST | t.CPtr] | t.CPtr, - node: AST | t.CPtr): +def _append_str_value(pool: rowptr[memhub.MemManager], + values: rowptr[list[rowptr[AST]]], + node: rowptr[AST]): """将字符串节点展开加入 values(JoinedStr 展开其 values,其余直接追加)""" if node is None: return if node.kind() == ASTKind.JoinedStr: - js_val: JoinedStr | t.CPtr = (JoinedStr | t.CPtr)(node) + js_val: rowptr[JoinedStr] = (rowptr[JoinedStr])(node) if js_val.values is not None: n_v: t.CSizeT = js_val.values.__len__() i_v: t.CSizeT @@ -1209,8 +1217,8 @@ def _append_str_value(pool: memhub.MemManager | t.CPtr, values.append(node) -def _concat_str_nodes(pool: memhub.MemManager | t.CPtr, - a: AST | t.CPtr, b: AST | t.CPtr) -> AST | t.CPtr: +def _concat_str_nodes(pool: rowptr[memhub.MemManager], + a: rowptr[AST], b: rowptr[AST]) -> rowptr[AST]: """合并相邻字符串字面量节点(Python 隐式拼接 "a" "b" → "ab") 纯常量字符串直接拼接文本;涉及 f-string(JoinedStr/FormattedValue)时 @@ -1222,8 +1230,8 @@ def _concat_str_nodes(pool: memhub.MemManager | t.CPtr, return a # 两个都是常量字符串 → 直接拼接文本 if a.kind() == ASTKind.Constant and b.kind() == ASTKind.Constant: - ca_c: Constant | t.CPtr = (Constant | t.CPtr)(a) - cb_c: Constant | t.CPtr = (Constant | t.CPtr)(b) + ca_c: rowptr[Constant] = (rowptr[Constant])(a) + cb_c: rowptr[Constant] = (rowptr[Constant])(b) if ca_c.const_kind == CONST_STR and cb_c.const_kind == CONST_STR \ and ca_c.str_val is not None and cb_c.str_val is not None: la_c: t.CSizeT = string.strlen(ca_c.str_val) @@ -1234,21 +1242,21 @@ def _concat_str_nodes(pool: memhub.MemManager | t.CPtr, string.memcpy(buf_c + la_c, cb_c.str_val, lb_c + 1) return _new_const_str(pool, buf_c, a.lineno, a.col_offset, 0, 0, 0) # 涉及 f-string → 合并到 JoinedStr - values_c: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](pool, 8) + values_c: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](pool, 8) _append_str_value(pool, values_c, a) _append_str_value(pool, values_c, b) if values_c.__len__() == 1: return values_c.get(0) - node_c: AST | t.CPtr = JoinedStr(pool, values_c) + node_c: rowptr[AST] = JoinedStr(pool, values_c) _set_pos(node_c, a.lineno, a.col_offset, 0, 0) return node_c -def _parse_fstring(ps: Parser | t.CPtr, content: str, - lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _parse_fstring(ps: rowptr[Parser], content: str, + lineno: int, col: int) -> rowptr[AST]: """Parse f-string content, building JoinedStr or FormattedValue nodes""" - pool: memhub.MemManager | t.CPtr = ps.pool - values: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](pool, 8) + pool: rowptr[memhub.MemManager] = ps.pool + values: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](pool, 8) i: t.CSizeT = 0 content_len: t.CSizeT = string.strlen(content) # Literal text buffer for f-string content @@ -1268,18 +1276,33 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, # Refresh literal buffer if lit_pos > 0: lit_buf[lit_pos] = '\0' - lit_node: AST | t.CPtr = _new_const_str(pool, lit_buf, lineno, col) + lit_node: rowptr[AST] = _new_const_str(pool, lit_buf, lineno, col) values.append(lit_node) lit_buf = pool.alloc(content_len + 1) if lit_buf is None: break lit_pos = 0 # Find matching closing '}' while tracking nested '{}' and string literals inside the f-string j: t.CSizeT = i + 1 - depth: t.CInt = 1 + depth: int = 1 conv_pos: t.CSizeT = 0 fmt_pos: t.CSizeT = 0 while j < content_len and depth > 0: c: t.CChar = content[j] + if c == '\'' or c == '"': + # 跳过表达式块内的嵌套字符串字面量(PEP 701 同引号嵌套), + # 避免其内部字符干扰 {} 深度/转换/格式分隔符定位 + nq: t.CChar = c + j += 1 + while j < content_len: + c2: t.CChar = content[j] + if c2 == '\\': + j += 2 + continue + if c2 == nq: + j += 1 + break + j += 1 + continue if c == '{': depth += 1 elif c == '}': @@ -1301,6 +1324,7 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, fmt_pos = j j += 1 if depth != 0: + _record_parse_err(ps) ps.error_count += 1 break # Extract expression text @@ -1311,6 +1335,7 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, expr_end = fmt_pos expr_len: t.CSizeT = expr_end - i - 1 if expr_len == 0: + _record_parse_err(ps) ps.error_count += 1 i = j + 1 continue @@ -1319,9 +1344,9 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, string.memcpy(expr_buf, content + i + 1, expr_len) expr_buf[expr_len] = '\0' # Parse expression text - expr_node: AST | t.CPtr = _parse_sub_expr(ps, expr_buf) + expr_node: rowptr[AST] = _parse_sub_expr(ps, expr_buf) # Conversion specifier - conversion: t.CInt = -1 + conversion: int = -1 if conv_pos > 0: conv_char: t.CChar = content[conv_pos + 1] if conv_char == 's': @@ -1331,7 +1356,7 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, elif conv_char == 'a': conversion = 97 # Format specifier - format_spec: AST | t.CPtr = None + format_spec: rowptr[AST] = None if fmt_pos > 0: spec_len: t.CSizeT = j - fmt_pos - 1 if spec_len > 0: @@ -1340,7 +1365,7 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, string.memcpy(spec_buf, content + fmt_pos + 1, spec_len) spec_buf[spec_len] = '\0' format_spec = _new_const_str(pool, spec_buf, lineno, col) - fv: AST | t.CPtr = FormattedValue(pool, expr_node, conversion, format_spec) + fv: rowptr[AST] = FormattedValue(pool, expr_node, conversion, format_spec) _set_pos(fv, lineno, col, 0, 0) values.append(fv) i = j + 1 @@ -1350,6 +1375,7 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, lit_pos += 1 i += 2 else: + _record_parse_err(ps) ps.error_count += 1 i += 1 else: @@ -1360,7 +1386,7 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, # Refresh remaining literal buffer if lit_pos > 0: lit_buf[lit_pos] = '\0' - lit_node2: AST | t.CPtr = _new_const_str(pool, lit_buf, lineno, col) + lit_node2: rowptr[AST] = _new_const_str(pool, lit_buf, lineno, col) values.append(lit_node2) # If no content, return empty string @@ -1368,19 +1394,19 @@ def _parse_fstring(ps: Parser | t.CPtr, content: str, return _new_const_str(pool, "", lineno, col) # If only one FormattedValue and no literal, return FormattedValue if values.__len__() == 1: - first: AST | t.CPtr = values.get(0) + first: rowptr[AST] = values.get(0) if first.kind() == ASTKind.FormattedValue: return first - node: AST | t.CPtr = JoinedStr(pool, values) + node: rowptr[AST] = JoinedStr(pool, values) _set_pos(node, lineno, col, 0, 0) return node -def _parse_comprehension(ps: Parser | t.CPtr, elt: AST | t.CPtr, - vtype: t.CInt, lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _parse_comprehension(ps: rowptr[Parser], elt: rowptr[AST], + vtype: int, lineno: int, col: int) -> rowptr[AST]: """General comprehension: elt comp_for""" - gens: list[AST | t.CPtr] | t.CPtr = _parse_comp_for(ps) - node: AST | t.CPtr = None + gens: rowptr[list[rowptr[AST]]] = _parse_comp_for(ps) + node: rowptr[AST] = None if vtype == ASTKind.ListComp: node = ListComp(ps.pool, elt, gens) elif vtype == ASTKind.SetComp: @@ -1391,81 +1417,81 @@ def _parse_comprehension(ps: Parser | t.CPtr, elt: AST | t.CPtr, return node -def _parse_comp_for(ps: Parser | t.CPtr) -> list[AST | t.CPtr] | t.CPtr: +def _parse_comp_for(ps: rowptr[Parser]) -> rowptr[list[rowptr[AST]]]: """comp_for: ['async'] 'for' exprlist 'in' or_test [comp_if] (comp_for)* Returns generators list。""" - gens: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + gens: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) while True: - is_async: t.CInt = 0 + is_async: int = 0 if _cur_kw(ps) == Keyword.Async: is_async = 1 _advance(ps) if _cur_kw(ps) != Keyword.For: break - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - target: AST | t.CPtr = _parse_target_list(ps) + target: rowptr[AST] = _parse_target_list(ps) if _cur_kw(ps) != Keyword.In: ps.error_count += 1 break _advance(ps) - iter_: AST | t.CPtr = _parse_or_test(ps) + iter_: rowptr[AST] = _parse_or_test(ps) # Collect ifs to list - ifs: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + ifs: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) while _cur_kw(ps) == Keyword.If: _advance(ps) - cond: AST | t.CPtr = _parse_or_test(ps) + cond: rowptr[AST] = _parse_or_test(ps) ifs.append(cond) - comp: AST | t.CPtr = Comprehension(ps.pool, target, iter_, ifs, is_async) + comp: rowptr[AST] = Comprehension(ps.pool, target, iter_, ifs, is_async) _set_pos(comp, lineno, col, 0, 0) gens.append(comp) return gens -def _parse_target_list(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_target_list(ps: rowptr[Parser]) -> rowptr[AST]: """Parse assignment target list (comma-separated)""" - first: AST | t.CPtr = _parse_target(ps) + first: rowptr[AST] = _parse_target(ps) if _match_op(ps, TokOp.Comma): - elts: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + elts: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) elts.append(first) while _accept_op(ps, TokOp.Comma): if _cur_kw(ps) == Keyword.In: break - e: AST | t.CPtr = _parse_target(ps) + e: rowptr[AST] = _parse_target(ps) elts.append(e) - node: AST | t.CPtr = Tuple(ps.pool, elts, ASTCtx.Store) + node: rowptr[AST] = Tuple(ps.pool, elts, ASTCtx.Store) _set_pos(node, first.lineno, first.col_offset, 0, 0) return node return first -def _parse_target(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_target(ps: rowptr[Parser]) -> rowptr[AST]: """Parse assignment target""" if _match_op(ps, TokOp.Star): _advance(ps) - inner: AST | t.CPtr = _parse_atom_expr(ps) - node: AST | t.CPtr = Starred(ps.pool, inner, ASTCtx.Store) + inner: rowptr[AST] = _parse_atom_expr(ps) + node: rowptr[AST] = Starred(ps.pool, inner, ASTCtx.Store) _set_pos(node, inner.lineno, inner.col_offset, 0, 0) return node if _match_op(ps, TokOp.LPar): _advance(ps) _skip_nl(ps) - t_: AST | t.CPtr = _parse_target_list(ps) + t_: rowptr[AST] = _parse_target_list(ps) _skip_nl(ps) _expect_op(ps, TokOp.RPar) return t_ if _match_op(ps, TokOp.Lsqb): _advance(ps) _skip_nl(ps) - first: AST | t.CPtr = _parse_target(ps) - elts: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + first: rowptr[AST] = _parse_target(ps) + elts: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) elts.append(first) while _accept_op(ps, TokOp.Comma): _skip_nl(ps) if _match_op(ps, TokOp.Rsqb): break - e: AST | t.CPtr = _parse_target(ps) + e: rowptr[AST] = _parse_target(ps) elts.append(e) _expect_op(ps, TokOp.Rsqb) node = List(ps.pool, elts, ASTCtx.Store) @@ -1478,17 +1504,17 @@ def _parse_target(ps: Parser | t.CPtr) -> AST | t.CPtr: return node -def _parse_yield(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_yield(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # yield if _cur_kw(ps) == Keyword.From: _advance(ps) - val: AST | t.CPtr = _parse_expr(ps) - node: AST | t.CPtr = YieldFrom(ps.pool, val) + val: rowptr[AST] = _parse_expr(ps) + node: rowptr[AST] = YieldFrom(ps.pool, val) _set_pos(node, lineno, col, 0, 0) return node - val2: AST | t.CPtr = None + val2: rowptr[AST] = None if not _match_op(ps, TokOp.RPar) and _cur_type(ps) != TokenType.NewLine and _cur_type(ps) != TokenType.EndMarker: if _cur_type(ps) == TokenType.Op and (_cur_op(ps) == TokOp.Comma or _cur_op(ps) == TokOp.Rsqb): pass @@ -1499,14 +1525,14 @@ def _parse_yield(ps: Parser | t.CPtr) -> AST | t.CPtr: return node -def _parse_varargslist(ps: Parser | t.CPtr, is_lambda: t.CInt = 0) -> AST | t.CPtr: +def _parse_varargslist(ps: rowptr[Parser], is_lambda: int = 0) -> rowptr[AST]: """Parse function parameter list New API: args/defaults/kw_defaults are lists, vararg/kwarg are fields.""" - args: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - vararg: AST | t.CPtr = None - kwarg: AST | t.CPtr = None - defaults: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - kw_defaults: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + args: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + vararg: rowptr[AST] = None + kwarg: rowptr[AST] = None + defaults: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + kw_defaults: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) while True: _skip_nl(ps) @@ -1539,12 +1565,12 @@ def _parse_varargslist(ps: Parser | t.CPtr, is_lambda: t.CInt = 0) -> AST | t.CP _skip_nl(ps) continue # Normal parameter - a: AST | t.CPtr = _parse_arg_def(ps, is_lambda) + a: rowptr[AST] = _parse_arg_def(ps, is_lambda) if a is None: break args.append(a) if _match_op(ps, TokOp.Equal): _advance(ps) - d: AST | t.CPtr = _parse_test(ps) + d: rowptr[AST] = _parse_test(ps) defaults.append(d) if not _accept_op(ps, TokOp.Comma): break @@ -1552,20 +1578,73 @@ def _parse_varargslist(ps: Parser | t.CPtr, is_lambda: t.CInt = 0) -> AST | t.CP return Arguments(ps.pool, args, vararg, kwarg, defaults, kw_defaults) -def _parse_arg_def(ps: Parser | t.CPtr, is_lambda: t.CInt = 0) -> AST | t.CPtr: +def _parse_type_ann(ps: rowptr[Parser]) -> rowptr[AST]: + """解析类型注解,支持 C 风格指针后缀(* / **)。 + + int* → rowptr[int] (i32*) + int** → (rowptr[int]) | t.CPtr (i32**) + int****** → 6 层嵌套 (i32******) + + _parse_test 会把后缀 '*' 消费为乘法(Mult)、'**' 消费为幂(Pow), + 右操作数解析失败时产生 BinOp(op, right=None) 垃圾节点并 error_count+1 + ('int***' 形态为 BinOp(Pow, UnaryOp(Deref, None)),StarStar+Star)。 + 本函数回收该形态并恢复 error_count,再按层数嵌套构造 BinOp(BitOr, t.CPtr)。 + """ + before_ec: int = ps.error_count + base: rowptr[AST] = _parse_test(ps) + if base is None: + _record_parse_err(ps) # 注解解析失败:记录具体位置(error_count 已在 _parse_test 内增加) + return None + ptr_level: int = 0 + # 回收垃圾节点(_parse_test 对后缀 * / ** 的消费产物) + if base.kind() == ASTKind.BinOp: + gb: rowptr[BinOp] = (rowptr[BinOp])(base) + if gb.op == OpKind.Mult and gb.right is None: + ptr_level += 1 + base = gb.left + elif gb.op == OpKind.Pow: + if gb.right is None: + ptr_level += 2 + base = gb.left + elif gb.right.kind() == ASTKind.UnaryOp: + gu: rowptr[UnaryOp] = (rowptr[UnaryOp])(gb.right) + if gu.op == OpKind.Deref and gu.operand is None: + ptr_level += 3 + base = gb.left + if ptr_level > 0: + ps.error_count = before_ec # 回收成功,恢复错误计数避免整文件解析失败 + # 循环消费残留后缀('**' 是词法单 token 计 2 层,'*' 计 1 层) + while _match_op(ps, TokOp.StarStar): + _advance(ps) + ptr_level += 2 + while _match_op(ps, TokOp.Star): + _advance(ps) + ptr_level += 1 + # 嵌套构造 rowptr[base](n 层) + li_an: int = 0 + while li_an < ptr_level: + cptr_an: rowptr[AST] = Attribute(ps.pool, + Name(ps.pool, "t", ASTCtx.Load), + "CPtr", ASTCtx.Load) + base = BinOp(ps.pool, base, OpKind.BitOr, cptr_an) + li_an += 1 + return base + + +def _parse_arg_def(ps: rowptr[Parser], is_lambda: int = 0) -> rowptr[AST]: """arg: TokenType.Name [':' annotation]""" if _cur_type(ps) != TokenType.Name: ps.error_count += 1 return None name_str: str = _cur_str(ps) - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - annotation: AST | t.CPtr = None + annotation: rowptr[AST] = None if is_lambda == 0: if _accept_op(ps, TokOp.Colon): - annotation = _parse_test(ps) - result: AST | t.CPtr = Arg(ps.pool, name_str, annotation) + annotation = _parse_type_ann(ps) + result: rowptr[AST] = Arg(ps.pool, name_str, annotation) _set_pos(result, lineno, col, 0, 0) return result @@ -1574,7 +1653,7 @@ def _parse_arg_def(ps: Parser | t.CPtr, is_lambda: t.CInt = 0) -> AST | t.CPtr: # Statement parsing (Design: directly append to parent, do not return a list) # ============================================================ -def _parse_suite_into_children(ps: Parser | t.CPtr, parent: AST | t.CPtr): +def _parse_suite_into_children(ps: rowptr[Parser], parent: rowptr[AST]): """Parse statement suite, directly append to parent's children. suite: TokenType.NewLine TokenType.Indent stmt+ TokenType.Dedent | simple_stmt""" _skip_nl(ps) @@ -1585,13 +1664,13 @@ def _parse_suite_into_children(ps: Parser | t.CPtr, parent: AST | t.CPtr): ps.error_count += 1 return _advance(ps) - sidx: t.CInt = 0 + sidx: int = 0 while _cur_type(ps) != TokenType.Dedent and _cur_type(ps) != TokenType.EndMarker: sidx += 1 # Decorator (class body methods can have decorators) if _match_op(ps, TokOp.At): ps.pending_decorators = _parse_decorators(ps) - before_cur: Token | t.CPtr = ps.cur + before_cur: rowptr[Token] = ps.cur _parse_statement_into(ps, parent) # Defensive: if parse did not advance token, force advance to avoid infinite loop if ps.cur is before_cur: @@ -1604,13 +1683,13 @@ def _parse_suite_into_children(ps: Parser | t.CPtr, parent: AST | t.CPtr): _parse_simple_stmt_into(ps, parent) -def _parse_statement_into(ps: Parser | t.CPtr, parent: AST | t.CPtr): +def _parse_statement_into(ps: rowptr[Parser], parent: rowptr[AST]): """Parse statement (compound or simple), append to the parent.""" - ttype: t.CInt = _cur_type(ps) - kw: t.CInt = _cur_kw(ps) + ttype: int = _cur_type(ps) + kw: int = _cur_kw(ps) if ttype == TokenType.Name: if kw == Keyword.If or kw == Keyword.While or kw == Keyword.For or kw == Keyword.Try: - stmt: AST | t.CPtr = _parse_compound(ps) + stmt: rowptr[AST] = _parse_compound(ps) if stmt is not None: parent.append(stmt) return @@ -1627,15 +1706,15 @@ def _parse_statement_into(ps: Parser | t.CPtr, parent: AST | t.CPtr): _parse_simple_stmt_into(ps, parent) -def _parse_simple_stmt_into(ps: Parser | t.CPtr, parent: AST | t.CPtr): +def _parse_simple_stmt_into(ps: rowptr[Parser], parent: rowptr[AST]): """simple_stmt: small_stmt (';' small_stmt)* [';'] TokenType.NewLine""" - first: AST | t.CPtr = _parse_small_stmt(ps) + first: rowptr[AST] = _parse_small_stmt(ps) if first is not None: parent.append(first) while _accept_op(ps, TokOp.Semi): if _cur_type(ps) == TokenType.NewLine or _cur_type(ps) == TokenType.EndMarker: break - s: AST | t.CPtr = _parse_small_stmt(ps) + s: rowptr[AST] = _parse_small_stmt(ps) if s is None: break parent.append(s) # 先跳过 Nl(括号内换行,如多行函数调用参数间的换行,属合法 token) @@ -1650,22 +1729,22 @@ def _parse_simple_stmt_into(ps: Parser | t.CPtr, parent: AST | t.CPtr): if err_str is None: err_str = "(none)" # 定位:从链表头找 cur,记录前一个 token 与下一个 token 的上下文 - prev_tok: Token | t.CPtr = None - walk_tok: Token | t.CPtr = ps.tokens + prev_tok: rowptr[Token] = None + walk_tok: rowptr[Token] = ps.tokens while walk_tok is not None and walk_tok is not ps.cur: prev_tok = walk_tok walk_tok = walk_tok.next pv_str: str = "(head)" - pv_line: t.CInt = 0 - pv_col: t.CInt = 0 + pv_line: int = 0 + pv_col: int = 0 if prev_tok is not None: pv_str = prev_tok.str_val pv_line = prev_tok.lineno pv_col = prev_tok.col_offset - nxt_tok: Token | t.CPtr = ps.cur.next + nxt_tok: rowptr[Token] = ps.cur.next nxt_str: str = "(none)" - nxt_line: t.CInt = 0 - nxt_col: t.CInt = 0 + nxt_line: int = 0 + nxt_col: int = 0 if nxt_tok is not None: nxt_str = nxt_tok.str_val nxt_line = nxt_tok.lineno @@ -1681,14 +1760,14 @@ def _parse_simple_stmt_into(ps: Parser | t.CPtr, parent: AST | t.CPtr): _advance(ps) -def _parse_small_stmt(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_small_stmt(ps: rowptr[Parser]) -> rowptr[AST]: """small_stmt: various simple statements""" - kw: t.CInt = _cur_kw(ps) + kw: int = _cur_kw(ps) if kw == Keyword.Pass: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - node: AST | t.CPtr = Pass(ps.pool) + node: rowptr[AST] = Pass(ps.pool) _set_pos(node, lineno, col, 0, 0) return node if kw == Keyword.Break: @@ -1727,41 +1806,41 @@ def _parse_small_stmt(ps: Parser | t.CPtr) -> AST | t.CPtr: return _parse_expr_stmt(ps, None) -def _maybe_tuple(ps: Parser | t.CPtr, first: AST | t.CPtr) -> AST | t.CPtr: +def _maybe_tuple(ps: rowptr[Parser], first: rowptr[AST]) -> rowptr[AST]: """If there is a comma after first, collect the comma-separated expressions into a Tuple.""" if first is None: return None if not _match_op(ps, TokOp.Comma): return first - lineno: t.CInt = first.lineno - col: t.CInt = first.col_offset - elts: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + lineno: int = first.lineno + col: int = first.col_offset + elts: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) elts.append(first) _accept_op(ps, TokOp.Comma) while True: - tt: t.CInt = _cur_type(ps) + tt: int = _cur_type(ps) if tt == TokenType.NewLine or tt == TokenType.EndMarker: break if tt == TokenType.Op: - op: t.CInt = _cur_op(ps) + op: int = _cur_op(ps) if op == TokOp.Equal or op == TokOp.Semi: break - e: AST | t.CPtr = _parse_expr(ps) + e: rowptr[AST] = _parse_expr(ps) if e is None: break elts.append(e) if not _accept_op(ps, TokOp.Comma): break - node: AST | t.CPtr = Tuple(ps.pool, elts, ASTCtx.Load) + node: rowptr[AST] = Tuple(ps.pool, elts, ASTCtx.Load) _set_pos(node, lineno, col, 0, 0) return node -def _parse_testlist(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_testlist(ps: rowptr[Parser]) -> rowptr[AST]: """Parse a comma-separated list of expressions, if there’s more than one, form a tuple.""" - first: AST | t.CPtr = _parse_expr(ps) + first: rowptr[AST] = _parse_expr(ps) return _maybe_tuple(ps, first) -def _parse_expr_stmt(ps: Parser | t.CPtr, first: AST | t.CPtr) -> AST | t.CPtr: +def _parse_expr_stmt(ps: rowptr[Parser], first: rowptr[AST]) -> rowptr[AST]: """Expression statement, handle assignment/augassign/annassign""" if first is None: first = _parse_testlist(ps) @@ -1769,42 +1848,42 @@ def _parse_expr_stmt(ps: Parser | t.CPtr, first: AST | t.CPtr) -> AST | t.CPtr: first = _maybe_tuple(ps, first) if first is None: return None - lineno: t.CInt = first.lineno - col: t.CInt = first.col_offset + lineno: int = first.lineno + col: int = first.col_offset # Assignment if _match_op(ps, TokOp.Equal): - targets: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + targets: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) targets.append(first) _fix_store_ctx(first) - value: AST | t.CPtr = None - accept_result: t.CInt = _accept_op(ps, TokOp.Equal) + value: rowptr[AST] = None + accept_result: int = _accept_op(ps, TokOp.Equal) while accept_result: - v: AST | t.CPtr = _parse_testlist(ps) + v: rowptr[AST] = _parse_testlist(ps) if v is None: break if value is not None: targets.append(value) _fix_store_ctx(value) value = v accept_result = _accept_op(ps, TokOp.Equal) - node: AST | t.CPtr = Assign(ps.pool, targets, value) + node: rowptr[AST] = Assign(ps.pool, targets, value) _set_pos(node, lineno, col, 0, 0) return node # augassign if _cur_type(ps) == TokenType.Op: - op_id: t.CInt = _cur_op(ps) - aug_op: t.CInt = _augop_from_op(op_id) + op_id: int = _cur_op(ps) + aug_op: int = _augop_from_op(op_id) if aug_op != OpKind.NoneOp: _advance(ps) - value2: AST | t.CPtr = _parse_testlist(ps) + value2: rowptr[AST] = _parse_testlist(ps) _fix_store_ctx(first) - node2: AST | t.CPtr = AugAssign(ps.pool, first, aug_op, value2) + node2: rowptr[AST] = AugAssign(ps.pool, first, aug_op, value2) _set_pos(node2, lineno, col, 0, 0) return node2 # annassign: target ':' annotation [= value] if _match_op(ps, TokOp.Colon): _advance(ps) - annotation: AST | t.CPtr = _parse_test(ps) - value3: AST | t.CPtr = None + annotation: rowptr[AST] = _parse_type_ann(ps) + value3: rowptr[AST] = None if _accept_op(ps, TokOp.Equal): value3 = _parse_testlist(ps) if ps.pool is None: @@ -1812,52 +1891,52 @@ def _parse_expr_stmt(ps: Parser | t.CPtr, first: AST | t.CPtr) -> AST | t.CPtr: _fix_store_ctx(first) if ps.pool is None: return None - node3: AST | t.CPtr = AnnAssign(ps.pool, first, annotation, value3, 1) + node3: rowptr[AST] = AnnAssign(ps.pool, first, annotation, value3, 1) _set_pos(node3, lineno, col, 0, 0) return node3 # Expression statement - node4: AST | t.CPtr = Expr(ps.pool, first) + node4: rowptr[AST] = Expr(ps.pool, first) _set_pos(node4, lineno, col, 0, 0) return node4 -def _parse_return(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_return(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - val: AST | t.CPtr = None + val: rowptr[AST] = None if _cur_type(ps) != TokenType.NewLine and _cur_type(ps) != TokenType.EndMarker and _cur_type(ps) != TokenType.Op: val = _parse_testlist(ps) elif _cur_type(ps) == TokenType.Op and _cur_op(ps) != TokOp.Semi: val = _parse_testlist(ps) - node: AST | t.CPtr = Return(ps.pool, val) + node: rowptr[AST] = Return(ps.pool, val) _set_pos(node, lineno, col, 0, 0) return node -def _parse_raise(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_raise(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - exc: AST | t.CPtr = None - cause: AST | t.CPtr = None + exc: rowptr[AST] = None + cause: rowptr[AST] = None if _cur_type(ps) != TokenType.NewLine and _cur_type(ps) != TokenType.EndMarker: exc = _parse_test(ps) if _cur_kw(ps) == Keyword.From: _advance(ps) cause = _parse_test(ps) - node: AST | t.CPtr = Raise(ps.pool, exc, cause) + node: rowptr[AST] = Raise(ps.pool, exc, cause) _set_pos(node, lineno, col, 0, 0) return node -def _parse_global(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_global(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - names: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + names: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) if _cur_type(ps) == TokenType.Name: - n: AST | t.CPtr = Name(ps.pool, _cur_str(ps), ASTCtx.Store) + n: rowptr[AST] = Name(ps.pool, _cur_str(ps), ASTCtx.Store) _set_pos(n, _cur_lineno(ps), _cur_col(ps), 0, 0) names.append(n) _advance(ps) @@ -1867,18 +1946,18 @@ def _parse_global(ps: Parser | t.CPtr) -> AST | t.CPtr: _set_pos(n, _cur_lineno(ps), _cur_col(ps), 0, 0) names.append(n) _advance(ps) - node: AST | t.CPtr = Global(ps.pool, names) + node: rowptr[AST] = Global(ps.pool, names) _set_pos(node, lineno, col, 0, 0) return node -def _parse_nonlocal(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_nonlocal(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - names: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + names: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) if _cur_type(ps) == TokenType.Name: - n: AST | t.CPtr = Name(ps.pool, _cur_str(ps), ASTCtx.Store) + n: rowptr[AST] = Name(ps.pool, _cur_str(ps), ASTCtx.Store) _set_pos(n, _cur_lineno(ps), _cur_col(ps), 0, 0) names.append(n) _advance(ps) @@ -1888,27 +1967,27 @@ def _parse_nonlocal(ps: Parser | t.CPtr) -> AST | t.CPtr: _set_pos(n, _cur_lineno(ps), _cur_col(ps), 0, 0) names.append(n) _advance(ps) - node: AST | t.CPtr = Nonlocal(ps.pool, names) + node: rowptr[AST] = Nonlocal(ps.pool, names) _set_pos(node, lineno, col, 0, 0) return node -def _parse_import(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_import(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - names: list[AST | t.CPtr] | t.CPtr = _parse_alias_list(ps) - node: AST | t.CPtr = Import(ps.pool, names) + names: rowptr[list[rowptr[AST]]] = _parse_alias_list(ps) + node: rowptr[AST] = Import(ps.pool, names) _set_pos(node, lineno, col, 0, 0) return node -def _parse_from_import(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_from_import(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # Parse module (possibly with dots) - level: t.CInt = 0 + level: int = 0 while _match_op(ps, TokOp.Dot): level += 1 _advance(ps) @@ -1928,8 +2007,8 @@ def _parse_from_import(ps: Parser | t.CPtr) -> AST | t.CPtr: _advance(ps) if _cur_type(ps) == TokenType.Name and _cur_kw(ps) == Keyword.NotKeyword: next_name: str = _cur_str(ps) - mlen: t.CInt = string.strlen(module_name) - nlen: t.CInt = string.strlen(next_name) + mlen: int = string.strlen(module_name) + nlen: int = string.strlen(next_name) new_mod: str = ps.pool.alloc(mlen + 1 + nlen + 1) if new_mod is not None: string.strcpy(new_mod, module_name) @@ -1945,44 +2024,44 @@ def _parse_from_import(ps: Parser | t.CPtr) -> AST | t.CPtr: # import * if _match_op(ps, TokOp.Star): _advance(ps) - star_alias: AST | t.CPtr = Alias(ps.pool, "*", None) + star_alias: rowptr[AST] = Alias(ps.pool, "*", None) _set_pos(star_alias, lineno, col, 0, 0) - star_names: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + star_names: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) star_names.append(star_alias) - node: AST | t.CPtr = ImportFrom(ps.pool, module_name, star_names, level) + node: rowptr[AST] = ImportFrom(ps.pool, module_name, star_names, level) _set_pos(node, lineno, col, 0, 0) return node # ( names ) or names if _match_op(ps, TokOp.LPar): _advance(ps) _skip_nl(ps) - names: list[AST | t.CPtr] | t.CPtr = _parse_alias_list(ps) + names: rowptr[list[rowptr[AST]]] = _parse_alias_list(ps) _skip_nl(ps) _expect_op(ps, TokOp.RPar) else: names = _parse_alias_list(ps) - node: AST | t.CPtr = ImportFrom(ps.pool, module_name, names, level) + node: rowptr[AST] = ImportFrom(ps.pool, module_name, names, level) _set_pos(node, lineno, col, 0, 0) return node -def _parse_alias_list(ps: Parser | t.CPtr) -> list[AST | t.CPtr] | t.CPtr: +def _parse_alias_list(ps: rowptr[Parser]) -> rowptr[list[rowptr[AST]]]: """Parse alias list.""" - names: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + names: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) while True: if _cur_type(ps) != TokenType.Name: break name_str: str = _cur_str(ps) - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # dotted name while _match_op(ps, TokOp.Dot): _advance(ps) if _cur_type(ps) == TokenType.Name: next_n: str = _cur_str(ps) - nmlen: t.CInt = string.strlen(name_str) - nxtlen: t.CInt = string.strlen(next_n) + nmlen: int = string.strlen(name_str) + nxtlen: int = string.strlen(next_n) new_name: str = ps.pool.alloc(nmlen + 1 + nxtlen + 1) if new_name is not None: string.strcpy(new_name, name_str) @@ -1996,7 +2075,7 @@ def _parse_alias_list(ps: Parser | t.CPtr) -> list[AST | t.CPtr] | t.CPtr: if _cur_type(ps) == TokenType.Name: asname = _cur_str(ps) _advance(ps) - a: AST | t.CPtr = Alias(ps.pool, name_str, asname) + a: rowptr[AST] = Alias(ps.pool, name_str, asname) _set_pos(a, lineno, col, 0, 0) names.append(a) if not _accept_op(ps, TokOp.Comma): @@ -2005,32 +2084,32 @@ def _parse_alias_list(ps: Parser | t.CPtr) -> list[AST | t.CPtr] | t.CPtr: return names -def _parse_del(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_del(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - targets: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + targets: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) while True: - t_: AST | t.CPtr = _parse_atom_expr(ps) + t_: rowptr[AST] = _parse_atom_expr(ps) if t_ is None: break _set_ctx(t_, ASTCtx.Del) targets.append(t_) if not _accept_op(ps, TokOp.Comma): break - node: AST | t.CPtr = Delete(ps.pool, targets) + node: rowptr[AST] = Delete(ps.pool, targets) _set_pos(node, lineno, col, 0, 0) return node -def _parse_assert(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_assert(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - test: AST | t.CPtr = _parse_test(ps) - msg: AST | t.CPtr = None + test: rowptr[AST] = _parse_test(ps) + msg: rowptr[AST] = None if _accept_op(ps, TokOp.Comma): msg = _parse_test(ps) - node: AST | t.CPtr = Assert(ps.pool, test, msg) + node: rowptr[AST] = Assert(ps.pool, test, msg) _set_pos(node, lineno, col, 0, 0) return node @@ -2039,8 +2118,8 @@ def _parse_assert(ps: Parser | t.CPtr) -> AST | t.CPtr: # Compound statements # ============================================================ -def _parse_compound(ps: Parser | t.CPtr) -> AST | t.CPtr: - kw: t.CInt = _cur_kw(ps) +def _parse_compound(ps: rowptr[Parser]) -> rowptr[AST]: + kw: int = _cur_kw(ps) if kw == Keyword.If: return _parse_if(ps) if kw == Keyword.While: @@ -2071,112 +2150,112 @@ def _parse_compound(ps: Parser | t.CPtr) -> AST | t.CPtr: return None -def _parse_if(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_if(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # if - test: AST | t.CPtr = _parse_test(ps) + test: rowptr[AST] = _parse_test(ps) _expect_op(ps, TokOp.Colon) # First construct with empty orelse, then fill it in later - empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - node: If | t.CPtr = If(ps.pool, test, empty) + empty: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + node: rowptr[If] = If(ps.pool, test, empty) _parse_suite_into_children(ps, node) - orelse: list[AST | t.CPtr] | t.CPtr = _parse_if_tail(ps) + orelse: rowptr[list[rowptr[AST]]] = _parse_if_tail(ps) node.orelse = orelse _set_pos(node, lineno, col, 0, 0) return node -def _parse_if_tail(ps: Parser | t.CPtr) -> list[AST | t.CPtr] | t.CPtr: +def _parse_if_tail(ps: rowptr[Parser]) -> rowptr[list[rowptr[AST]]]: """Parse elif/else chain and return orelse list. elif: orelse = list containing single If node (nested) else: orelse = statement list """ if _cur_kw(ps) == Keyword.Elif: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) - elif_test: AST | t.CPtr = _parse_test(ps) + elif_test: rowptr[AST] = _parse_test(ps) _expect_op(ps, TokOp.Colon) - empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - elif_node: If | t.CPtr = If(ps.pool, elif_test, empty) + empty: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + elif_node: rowptr[If] = If(ps.pool, elif_test, empty) _parse_suite_into_children(ps, elif_node) - elif_orelse: list[AST | t.CPtr] | t.CPtr = _parse_if_tail(ps) + elif_orelse: rowptr[list[rowptr[AST]]] = _parse_if_tail(ps) elif_node.orelse = elif_orelse _set_pos(elif_node, lineno, col, 0, 0) - orelse: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + orelse: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) orelse.append(elif_node) return orelse if _cur_kw(ps) == Keyword.Else: _advance(ps) _expect_op(ps, TokOp.Colon) - scratch: Module | t.CPtr = Module(ps.pool) + scratch: rowptr[Module] = Module(ps.pool) _parse_suite_into_children(ps, scratch) return scratch.children - return list[AST | t.CPtr](ps.pool, 8) # 空 list + return list[rowptr[AST]](ps.pool, 8) # 空 list # ============================================================ # Parsing Compound Statements (Continued) # ============================================================ -def _parse_while(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_while(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # while - test: AST | t.CPtr = _parse_test(ps) + test: rowptr[AST] = _parse_test(ps) _expect_op(ps, TokOp.Colon) - empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - node: While | t.CPtr = While(ps.pool, test, empty) + empty: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + node: rowptr[While] = While(ps.pool, test, empty) _parse_suite_into_children(ps, node) if _cur_kw(ps) == Keyword.Else: _advance(ps) _expect_op(ps, TokOp.Colon) - scratch: Module | t.CPtr = Module(ps.pool) + scratch: rowptr[Module] = Module(ps.pool) _parse_suite_into_children(ps, scratch) node.orelse = scratch.children _set_pos(node, lineno, col, 0, 0) return node -def _parse_for(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_for(ps: rowptr[Parser], is_async: int) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # for - target: AST | t.CPtr = _parse_target_list(ps) + target: rowptr[AST] = _parse_target_list(ps) if _cur_kw(ps) != Keyword.In: ps.error_count += 1 return None _advance(ps) - iter_: AST | t.CPtr = _parse_or_test(ps) + iter_: rowptr[AST] = _parse_or_test(ps) _expect_op(ps, TokOp.Colon) - empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - node: For | t.CPtr = For(ps.pool, target, iter_, empty, is_async) + empty: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + node: rowptr[For] = For(ps.pool, target, iter_, empty, is_async) _fix_store_ctx(target) _parse_suite_into_children(ps, node) if _cur_kw(ps) == Keyword.Else: _advance(ps) _expect_op(ps, TokOp.Colon) - scratch: Module | t.CPtr = Module(ps.pool) + scratch: rowptr[Module] = Module(ps.pool) _parse_suite_into_children(ps, scratch) node.orelse = scratch.children _set_pos(node, lineno, col, 0, 0) return node -def _parse_try(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_try(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # try _expect_op(ps, TokOp.Colon) - empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - node: Try | t.CPtr = Try(ps.pool, empty, empty, empty) + empty: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + node: rowptr[Try] = Try(ps.pool, empty, empty, empty) _parse_suite_into_children(ps, node) # handlers (except) - handlers: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + handlers: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) while _cur_kw(ps) == Keyword.Except: - h: AST | t.CPtr = _parse_except_handler(ps) + h: rowptr[AST] = _parse_except_handler(ps) if h is not None: handlers.append(h) node.handlers = handlers @@ -2184,25 +2263,25 @@ def _parse_try(ps: Parser | t.CPtr) -> AST | t.CPtr: if _cur_kw(ps) == Keyword.Else: _advance(ps) _expect_op(ps, TokOp.Colon) - scratch: Module | t.CPtr = Module(ps.pool) + scratch: rowptr[Module] = Module(ps.pool) _parse_suite_into_children(ps, scratch) node.orelse = scratch.children # finally if _cur_kw(ps) == Keyword.Finally: _advance(ps) _expect_op(ps, TokOp.Colon) - scratch2: Module | t.CPtr = Module(ps.pool) + scratch2: rowptr[Module] = Module(ps.pool) _parse_suite_into_children(ps, scratch2) node.finalbody = scratch2.children _set_pos(node, lineno, col, 0, 0) return node -def _parse_except_handler(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_except_handler(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # except - type_: AST | t.CPtr = None + type_: rowptr[AST] = None name: str = None if _cur_op(ps) != TokOp.Colon: type_ = _parse_test(ps) @@ -2212,20 +2291,20 @@ def _parse_except_handler(ps: Parser | t.CPtr) -> AST | t.CPtr: name = _cur_str(ps) _advance(ps) _expect_op(ps, TokOp.Colon) - node: AST | t.CPtr = ExceptHandler(ps.pool, type_, name) + node: rowptr[AST] = ExceptHandler(ps.pool, type_, name) _parse_suite_into_children(ps, node) _set_pos(node, lineno, col, 0, 0) return node -def _parse_with(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_with(ps: rowptr[Parser], is_async: int) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # with - items: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + items: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) # items while True: - item: AST | t.CPtr = _parse_with_item(ps) + item: rowptr[AST] = _parse_with_item(ps) if item is None: break items.append(item) if not _accept_op(ps, TokOp.Comma): @@ -2234,33 +2313,34 @@ def _parse_with(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: if _cur_type(ps) == TokenType.NewLine or _cur_type(ps) == TokenType.Nl: break _expect_op(ps, TokOp.Colon) - node: With | t.CPtr = With(ps.pool, items, is_async) + node: rowptr[With] = With(ps.pool, items, is_async) _parse_suite_into_children(ps, node) _set_pos(node, lineno, col, 0, 0) return node -def _parse_with_item(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_with_item(ps: rowptr[Parser]) -> rowptr[AST]: """with_item: test ['as' expr]""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) - context_expr: AST | t.CPtr = _parse_or_test(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) + context_expr: rowptr[AST] = _parse_or_test(ps) if context_expr is None: return None - optional_vars: AST | t.CPtr = None + optional_vars: rowptr[AST] = None if _cur_kw(ps) == Keyword.As: _advance(ps) optional_vars = _parse_target(ps) _fix_store_ctx(optional_vars) - node: AST | t.CPtr = WithItem(ps.pool, context_expr, optional_vars) + node: rowptr[AST] = WithItem(ps.pool, context_expr, optional_vars) _set_pos(node, lineno, col, 0, 0) return node -def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) - is_extern_fd: t.CInt = 0 - is_export_fd: t.CInt = 0 +def _parse_funcdef(ps: rowptr[Parser], is_async: int) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) + is_extern_fd: int = 0 + is_export_fd: int = 0 + is_define_fd: int = 0 if _cur_kw(ps) == Keyword.Extern: # extern 声明:extern [def] A(...) [-> T] [": pass" 可选] is_extern_fd = 1 @@ -2273,6 +2353,11 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: _advance(ps) # export if _cur_kw(ps) == Keyword.Def: _advance(ps) + elif _cur_kw(ps) == Keyword.Define: + # define 宏函数:语法与 def 完全一致,返回注解自动追加 t.CDefine + # 标记为宏函数(StubGen 保留原样 → C #define / alwaysinline 内联) + is_define_fd = 1 + _advance(ps) # define else: _advance(ps) # def / fn / ... if _cur_type(ps) != TokenType.Name: @@ -2284,7 +2369,7 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: # (与 class 解析器一致;之前缺失此处理导致 _expect_op(Colon) 失败、函数体被 # 误提升到模块级——b = Box(42) 被当作模块级全局注册,函数内赋值误报 # "需用 global 声明"。翻译时 type_params 映射到 int 兜底。) - type_params_fd: list[str] | t.CPtr = None + type_params_fd: rowptr[list[str]] = None if _accept_op(ps, TokOp.Lsqb): type_params_fd = list[str](ps.pool, 8) while not _match_op(ps, TokOp.Rsqb): @@ -2301,17 +2386,17 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: if not _accept_op(ps, TokOp.Comma): break _expect_op(ps, TokOp.Rsqb) - args: AST | t.CPtr = None + args: rowptr[AST] = None if _accept_op(ps, TokOp.LPar): args = _parse_varargslist(ps, 0) _expect_op(ps, TokOp.RPar) - returns: AST | t.CPtr = None + returns: rowptr[AST] = None if _accept_op(ps, TokOp.RArrow): - returns = _parse_test(ps) + returns = _parse_type_ann(ps) if is_extern_fd: # extern 声明:返回注解改写为 <原类型> | t.State,复用既有 # State/外部 C 函数识别路径(vpi 注解含 "State" → 定义端裸名 + 不生成函数体) - state_attr_fd: AST | t.CPtr = Attribute(ps.pool, + state_attr_fd: rowptr[AST] = Attribute(ps.pool, Name(ps.pool, "t", ASTCtx.Load), "State", ASTCtx.Load) if returns != None: @@ -2321,21 +2406,33 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: elif is_export_fd: # export 声明:返回注解改写为 <原类型> | t.CExport,复用既有 # CExport 识别路径(vpi 注解含 "CExport" → 定义端裸名 + 不加模块 SHA1 头) - export_attr_fd: AST | t.CPtr = Attribute(ps.pool, + export_attr_fd: rowptr[AST] = Attribute(ps.pool, Name(ps.pool, "t", ASTCtx.Load), "CExport", ASTCtx.Load) if returns != None: returns = BinOp(ps.pool, returns, OpKind.BitOr, export_attr_fd) else: returns = export_attr_fd - dec_list: list[AST | t.CPtr] | t.CPtr = ps.pending_decorators + elif is_define_fd: + # define 宏函数:返回注解改写为 <原类型> | t.CDefine,复用既有 + # CDefine 宏函数识别路径(StubGen 保留原样 → C #define / alwaysinline) + define_attr_fd: rowptr[AST] = Attribute(ps.pool, + Name(ps.pool, "t", ASTCtx.Load), + "CDefine", ASTCtx.Load) + if returns != None: + returns = BinOp(ps.pool, returns, OpKind.BitOr, define_attr_fd) + else: + returns = define_attr_fd + dec_list: rowptr[list[rowptr[AST]]] = ps.pending_decorators ps.pending_decorators = None - node: FunctionDef | t.CPtr = FunctionDef(ps.pool, name, args, dec_list, returns, is_async, type_params_fd) + node: rowptr[FunctionDef] = FunctionDef(ps.pool, name, args, dec_list, returns, is_async, type_params_fd) if is_extern_fd: node.flags = node.flags | FLAG_IS_EXTERN if is_export_fd: node.flags = node.flags | FLAG_IS_EXPORT - if (is_extern_fd == 0 and is_export_fd == 0) or _match_op(ps, TokOp.Colon): + if is_define_fd: + node.flags = node.flags | FLAG_IS_DEFINE + if (is_extern_fd == 0 and is_export_fd == 0 and is_define_fd == 0) or _match_op(ps, TokOp.Colon): _expect_op(ps, TokOp.Colon) _parse_suite_into_children(ps, node) else: @@ -2349,9 +2446,9 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr: return node -def _parse_classdef(ps: Parser | t.CPtr) -> AST | t.CPtr: - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) +def _parse_classdef(ps: rowptr[Parser]) -> rowptr[AST]: + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # class if _cur_type(ps) != TokenType.Name: ps.error_count += 1 @@ -2359,7 +2456,7 @@ def _parse_classdef(ps: Parser | t.CPtr) -> AST | t.CPtr: name: str = _cur_str(ps) _advance(ps) # Parse type parameters [T] or [T, U] (PEP 695 generic class syntax) - type_params: list[str] | t.CPtr = None + type_params: rowptr[list[str]] = None if _accept_op(ps, TokOp.Lsqb): type_params = list[str](ps.pool, 8) while not _match_op(ps, TokOp.Rsqb): @@ -2375,8 +2472,8 @@ def _parse_classdef(ps: Parser | t.CPtr) -> AST | t.CPtr: if not _accept_op(ps, TokOp.Comma): break _expect_op(ps, TokOp.Rsqb) - bases: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - keywords: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + bases: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + keywords: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) # bases / keywords if _accept_op(ps, TokOp.LPar): while not _match_op(ps, TokOp.RPar): @@ -2388,11 +2485,11 @@ def _parse_classdef(ps: Parser | t.CPtr) -> AST | t.CPtr: # base 或 keyword=value if _cur_type(ps) == TokenType.Name: # Parse as expression, if followed by '=', then as keyword=value - e: AST | t.CPtr = _parse_or_test(ps) + e: rowptr[AST] = _parse_or_test(ps) if _match_op(ps, TokOp.Equal): _advance(ps) - v: AST | t.CPtr = _parse_test(ps) - kw_node: AST | t.CPtr = KwNode(ps.pool, e, v) + v: rowptr[AST] = _parse_test(ps) + kw_node: rowptr[AST] = KwNode(ps.pool, e, v) keywords.append(kw_node) else: bases.append(e) @@ -2401,23 +2498,23 @@ def _parse_classdef(ps: Parser | t.CPtr) -> AST | t.CPtr: _skip_nl(ps) # 末基类后换行收尾(class X(A,\n B):) _expect_op(ps, TokOp.RPar) _expect_op(ps, TokOp.Colon) - dec_list: list[AST | t.CPtr] | t.CPtr = ps.pending_decorators + dec_list: rowptr[list[rowptr[AST]]] = ps.pending_decorators ps.pending_decorators = None - node: ClassDef | t.CPtr = ClassDef(ps.pool, name, bases, keywords, dec_list, type_params) + node: rowptr[ClassDef] = ClassDef(ps.pool, name, bases, keywords, dec_list, type_params) _parse_suite_into_children(ps, node) _set_pos(node, lineno, col, 0, 0) return node -def _parse_match(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_match(ps: rowptr[Parser]) -> rowptr[AST]: """match statement: match subject ':' NewLine Indent case+ Dedent""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # match - subject: AST | t.CPtr = _parse_test(ps) + subject: rowptr[AST] = _parse_test(ps) _expect_op(ps, TokOp.Colon) - cases: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - node: AST | t.CPtr = Match(ps.pool, subject, cases) + cases: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + node: rowptr[AST] = Match(ps.pool, subject, cases) # Parsing body: Same NewLine/Indent/Dedent pattern as _parse_suite_into_children, # but parses case clauses into a cases list instead of normal statements into children _skip_nl(ps) @@ -2428,7 +2525,7 @@ def _parse_match(ps: Parser | t.CPtr) -> AST | t.CPtr: _advance(ps) while _cur_type(ps) != TokenType.Dedent and _cur_type(ps) != TokenType.EndMarker: if _cur_kw(ps) == Keyword.Case: - case_node: AST | t.CPtr = _parse_match_case(ps) + case_node: rowptr[AST] = _parse_match_case(ps) if case_node is not None: cases.append(case_node) else: @@ -2442,25 +2539,25 @@ def _parse_match(ps: Parser | t.CPtr) -> AST | t.CPtr: # Match pattern parsing # ============================================================ -def _make_name_ast(pool: memhub.MemManager | t.CPtr, node: Name | t.CPtr) -> AST | t.CPtr: +def _make_name_ast(pool: rowptr[memhub.MemManager], node: rowptr[Name]) -> rowptr[AST]: # Analysis: "Convert Name* to AST* (Solving the TransPyC Type Inference Problem)" return node -def _parse_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_pattern(ps: rowptr[Parser]) -> rowptr[AST]: """pattern: or_pattern ['as' NAME] or_pattern: closed_pattern ('|' closed_pattern)*""" - pat: AST | t.CPtr = _parse_closed_pattern(ps) + pat: rowptr[AST] = _parse_closed_pattern(ps) if pat is None: return None # OR pattern if _match_op(ps, TokOp.VBar): - patterns: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + patterns: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) patterns.append(pat) while _accept_op(ps, TokOp.VBar): - p: AST | t.CPtr = _parse_closed_pattern(ps) + p: rowptr[AST] = _parse_closed_pattern(ps) if p is not None: patterns.append(p) - or_node: AST | t.CPtr = MatchOr(ps.pool, patterns) + or_node: rowptr[AST] = MatchOr(ps.pool, patterns) _set_pos(or_node, pat.lineno, pat.col_offset, 0, 0) pat = or_node # AS pattern @@ -2471,20 +2568,20 @@ def _parse_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: return pat name_str: str = _cur_str(ps) _advance(ps) - as_node: AST | t.CPtr = MatchAs(ps.pool, pat, name_str) + as_node: rowptr[AST] = MatchAs(ps.pool, pat, name_str) _set_pos(as_node, pat.lineno, pat.col_offset, 0, 0) return as_node return pat -def _parse_closed_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_closed_pattern(ps: rowptr[Parser]) -> rowptr[AST]: """closed_pattern: literal | capture | wildcard | value | group | sequence | mapping | class""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) - ttype: t.CInt = _cur_type(ps) - val: AST | t.CPtr - node: AST | t.CPtr - tok: Token | t.CPtr + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) + ttype: int = _cur_type(ps) + val: rowptr[AST] + node: rowptr[AST] + tok: rowptr[Token] sval: str # Number literal pattern @@ -2502,7 +2599,7 @@ def _parse_closed_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: # String literal pattern if ttype == TokenType.String: sval = _cur_str(ps) - is_dquote_m: t.CInt = ps.cur.kw_subtype & 16 + is_dquote_m: int = ps.cur.kw_subtype & 16 _advance(ps) val = _new_const_str(ps.pool, sval, lineno, col, is_dquote_m) node = MatchValue(ps.pool, val) @@ -2527,7 +2624,7 @@ def _parse_closed_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: # Name: None/True/False/_ /capture/value/class if ttype == TokenType.Name: - kw: t.CInt = _cur_kw(ps) + kw: int = _cur_kw(ps) # None/True/False → MatchSingleton if kw == Keyword.None_ or kw == Keyword.True_ or kw == Keyword.False_: _advance(ps) @@ -2550,17 +2647,17 @@ def _parse_closed_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: _advance(ps) # Check dotted name(value pattern 或 class pattern) if _match_op(ps, TokOp.Dot): - name_node: Name | t.CPtr = Name(ps.pool, name_str, ASTCtx.Load) + name_node: rowptr[Name] = Name(ps.pool, name_str, ASTCtx.Load) _set_pos(name_node, lineno, col, 0, 0) - base: AST | t.CPtr = _make_name_ast(ps.pool, name_node) + base: rowptr[AST] = _make_name_ast(ps.pool, name_node) while _match_op(ps, TokOp.Dot): _advance(ps) if _cur_type(ps) != TokenType.Name: ps.error_count += 1 break attr_name: str = _cur_str(ps) - attr_lineno: t.CInt = _cur_lineno(ps) - attr_col: t.CInt = _cur_col(ps) + attr_lineno: int = _cur_lineno(ps) + attr_col: int = _cur_col(ps) _advance(ps) base = Attribute(ps.pool, base, attr_name, ASTCtx.Load) _set_pos(base, attr_lineno, attr_col, 0, 0) @@ -2573,9 +2670,9 @@ def _parse_closed_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: return node # class pattern: Name(...) if _match_op(ps, TokOp.LPar): - cls_node: Name | t.CPtr = Name(ps.pool, name_str, ASTCtx.Load) + cls_node: rowptr[Name] = Name(ps.pool, name_str, ASTCtx.Load) _set_pos(cls_node, lineno, col, 0, 0) - cls: AST | t.CPtr = _make_name_ast(ps.pool, cls_node) + cls: rowptr[AST] = _make_name_ast(ps.pool, cls_node) return _parse_class_pattern(ps, cls, lineno, col) # capture pattern: NAME node = MatchAs(ps.pool, None, name_str) @@ -2585,14 +2682,14 @@ def _parse_closed_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: # group pattern / sequence pattern (tuple): (...) if _match_op(ps, TokOp.LPar): _advance(ps) - inner: AST | t.CPtr = _parse_pattern(ps) + inner: rowptr[AST] = _parse_pattern(ps) if _accept_op(ps, TokOp.Comma): # sequence pattern (tuple) - patterns: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + patterns: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) if inner is not None: patterns.append(inner) while not _match_op(ps, TokOp.RPar) and _cur_type(ps) != TokenType.EndMarker: - p: AST | t.CPtr = _parse_pattern(ps) + p: rowptr[AST] = _parse_pattern(ps) if p is not None: patterns.append(p) if not _accept_op(ps, TokOp.Comma): @@ -2616,10 +2713,10 @@ def _parse_closed_pattern(ps: Parser | t.CPtr) -> AST | t.CPtr: return None -def _parse_sequence_pattern(ps: Parser | t.CPtr, close_op: t.CInt, - lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _parse_sequence_pattern(ps: rowptr[Parser], close_op: int, + lineno: int, col: int) -> rowptr[AST]: """sequence_pattern: '[' [pattern_list] ']'""" - patterns: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + patterns: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) _advance(ps) # [ while not _match_op(ps, close_op) and _cur_type(ps) != TokenType.EndMarker: # *name (star pattern) @@ -2628,7 +2725,7 @@ def _parse_sequence_pattern(ps: Parser | t.CPtr, close_op: t.CInt, if _cur_type(ps) == TokenType.Name: star_name: str = _cur_str(ps) _advance(ps) - star_node: AST | t.CPtr + star_node: rowptr[AST] if string.strcmp(star_name, "_") == 0: star_node = MatchStar(ps.pool, None) else: @@ -2636,27 +2733,27 @@ def _parse_sequence_pattern(ps: Parser | t.CPtr, close_op: t.CInt, _set_pos(star_node, lineno, col, 0, 0) patterns.append(star_node) else: - p: AST | t.CPtr = _parse_pattern(ps) + p: rowptr[AST] = _parse_pattern(ps) if p is not None: patterns.append(p) if not _accept_op(ps, TokOp.Comma): break _expect_op(ps, close_op) - node: AST | t.CPtr = MatchSequence(ps.pool, patterns) + node: rowptr[AST] = MatchSequence(ps.pool, patterns) _set_pos(node, lineno, col, 0, 0) return node -def _parse_mapping_pattern(ps: Parser | t.CPtr, - lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _parse_mapping_pattern(ps: rowptr[Parser], + lineno: int, col: int) -> rowptr[AST]: """mapping_pattern: '{' [items] '}' items: key ':' pattern (',' key ':' pattern)* [',' '**' NAME] | '**' NAME""" - keys: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - patterns: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + keys: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + patterns: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) rest: str = None - node: AST | t.CPtr - key: AST | t.CPtr - val_pat: AST | t.CPtr + node: rowptr[AST] + key: rowptr[AST] + val_pat: rowptr[AST] _advance(ps) # { if _match_op(ps, TokOp.RBrace): _advance(ps) @@ -2685,30 +2782,30 @@ def _parse_mapping_pattern(ps: Parser | t.CPtr, return node -def _parse_class_pattern(ps: Parser | t.CPtr, cls: AST | t.CPtr, - lineno: t.CInt, col: t.CInt) -> AST | t.CPtr: +def _parse_class_pattern(ps: rowptr[Parser], cls: rowptr[AST], + lineno: int, col: int) -> rowptr[AST]: """class_pattern: cls '(' [pattern_list] ')' pattern_list: positional_pattern (',' positional_pattern)* [',' keyword_pattern]* | keyword_pattern (',' keyword_pattern)* keyword_pattern: NAME '=' pattern""" - patterns: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - kwd_attrs: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - kwd_patterns: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) - p: AST | t.CPtr + patterns: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + kwd_attrs: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + kwd_patterns: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) + p: rowptr[AST] _advance(ps) # ( if not _match_op(ps, TokOp.RPar): while _cur_type(ps) != TokenType.EndMarker: # keyword pattern: NAME '=' pattern if _cur_type(ps) == TokenType.Name and ps.cur is not None: - nxt: Token | t.CPtr = ps.cur.next + nxt: rowptr[Token] = ps.cur.next if nxt is not None and nxt.type == TokenType.Op and nxt.op_subtype == TokOp.Equal: attr_name: str = _cur_str(ps) _advance(ps) # NAME _advance(ps) # = - kwd_pat: AST | t.CPtr = _parse_pattern(ps) - attr_n: Name | t.CPtr = Name(ps.pool, attr_name, ASTCtx.Load) + kwd_pat: rowptr[AST] = _parse_pattern(ps) + attr_n: rowptr[Name] = Name(ps.pool, attr_name, ASTCtx.Load) _set_pos(attr_n, lineno, col, 0, 0) - attr_node: AST | t.CPtr = _make_name_ast(ps.pool, attr_n) + attr_node: rowptr[AST] = _make_name_ast(ps.pool, attr_n) kwd_attrs.append(attr_node) if kwd_pat is not None: kwd_patterns.append(kwd_pat) @@ -2723,36 +2820,36 @@ def _parse_class_pattern(ps: Parser | t.CPtr, cls: AST | t.CPtr, if not _accept_op(ps, TokOp.Comma): break _expect_op(ps, TokOp.RPar) - node: AST | t.CPtr = MatchClass(ps.pool, cls, patterns, kwd_attrs, kwd_patterns) + node: rowptr[AST] = MatchClass(ps.pool, cls, patterns, kwd_attrs, kwd_patterns) _set_pos(node, lineno, col, 0, 0) return node -def _parse_match_case(ps: Parser | t.CPtr) -> AST | t.CPtr: +def _parse_match_case(ps: rowptr[Parser]) -> rowptr[AST]: """case pattern [if guard] ':' suite""" - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # case - guard: AST | t.CPtr = None - pattern: AST | t.CPtr = _parse_pattern(ps) + guard: rowptr[AST] = None + pattern: rowptr[AST] = _parse_pattern(ps) if _cur_kw(ps) == Keyword.If: _advance(ps) guard = _parse_or_test(ps) _expect_op(ps, TokOp.Colon) - node: AST | t.CPtr = MatchCase(ps.pool, pattern, guard) + node: rowptr[AST] = MatchCase(ps.pool, pattern, guard) _parse_suite_into_children(ps, node) _set_pos(node, lineno, col, 0, 0) return node -def _parse_decorators(ps: Parser | t.CPtr) -> list[AST | t.CPtr] | t.CPtr: +def _parse_decorators(ps: rowptr[Parser]) -> rowptr[list[rowptr[AST]]]: """解析装饰器链,返回 list。""" - decs: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8) + decs: rowptr[list[rowptr[AST]]] = list[rowptr[AST]](ps.pool, 8) while _match_op(ps, TokOp.At): - lineno: t.CInt = _cur_lineno(ps) - col: t.CInt = _cur_col(ps) + lineno: int = _cur_lineno(ps) + col: int = _cur_col(ps) _advance(ps) # @ - expr: AST | t.CPtr = _parse_namedexpr(ps) + expr: rowptr[AST] = _parse_namedexpr(ps) _skip_nl(ps) if _cur_type(ps) == TokenType.NewLine: _advance(ps) @@ -2764,17 +2861,17 @@ def _parse_decorators(ps: Parser | t.CPtr) -> list[AST | t.CPtr] | t.CPtr: # Module entry # ============================================================ -def _parse_module_body(ps: Parser | t.CPtr, module_node: AST | t.CPtr): +def _parse_module_body(ps: rowptr[Parser], module_node: rowptr[AST]): """解析模块体,append 到 module_node。""" _skip_nl(ps) - stmt_idx: t.CInt = 0 + stmt_idx: int = 0 while _cur_type(ps) != TokenType.EndMarker: stmt_idx += 1 # Decorator if _match_op(ps, TokOp.At): ps.pending_decorators = _parse_decorators(ps) # Record current token pointer to check for infinite loop - before_cur: Token | t.CPtr = ps.cur + before_cur: rowptr[Token] = ps.cur _parse_statement_into(ps, module_node) # Defense: If parsing doesn't advance the token (like when _parse_atom encounters an unrecognized token and returns None), # force it to move forward to avoid an infinite loop in the main loop; accumulate error_count for the caller to diagnose @@ -2784,8 +2881,8 @@ def _parse_module_body(ps: Parser | t.CPtr, module_node: AST | t.CPtr): _skip_nl(ps) -def parse_tokens(pool: memhub.MemManager | t.CPtr, - tokens: Token | t.CPtr) -> AST | t.CPtr: +def parse_tokens(pool: rowptr[memhub.MemManager], + tokens: rowptr[Token]) -> rowptr[AST]: """Parse an AST Module from a token list.""" if pool is None or tokens is None: return None @@ -2793,10 +2890,10 @@ def parse_tokens(pool: memhub.MemManager | t.CPtr, _g_parse_err_line = 0 _g_parse_err_col = 0 _g_parse_err_msg = None - ps: Parser | t.CPtr = new_parser(pool) + ps: rowptr[Parser] = new_parser(pool) if ps is None: return None _parser_init(ps, tokens, pool) - module_node: Module | t.CPtr = Module(pool) + module_node: rowptr[Module] = Module(pool) _parse_module_body(ps, module_node) # fail-fast: 解析出错(error_count > 0)时返回 None,由调用方(TPV 等)报错终止, # 避免错误代码静默编译(如 `func12344444 avg3(...)` 缺 def 关键字的函数定义残留)。 diff --git a/ast/stmts.vp b/ast/stmts.vp index fccfab8..4b3d74d 100644 --- a/ast/stmts.vp +++ b/ast/stmts.vp @@ -16,24 +16,24 @@ from .base import ( @t.CVTable class Module(AST): - """Module(children: list[AST | t.CPtr])""" + """Module(children: list[rowptr[AST]])""" - def __new__(self, pool: memhub.MemManager | t.CPtr): - ptr: Module | t.CPtr = pool.alloc(Module.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager]): + ptr: rowptr[Module] = pool.alloc(Module.__sizeof__()) if ptr: string.memset(ptr, 0, Module.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager]): _init_ast(self, pool, 0, 0) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Module def type_name(self) -> str: return "Module" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Module(body=") pos = _dump_list(self.children, buf, size, pos) @@ -46,31 +46,31 @@ class Module(AST): # ============================================================ class Assign(Stmt): - """Assign(targets: list[AST | t.CPtr], value: AST)""" - targets: list[AST | t.CPtr] | t.CPtr - value: AST | t.CPtr + """Assign(targets: list[rowptr[AST]], value: AST)""" + targets: rowptr[list[rowptr[AST]]] + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - targets: list[AST | t.CPtr] | t.CPtr, value: AST | t.CPtr): - ptr: Assign | t.CPtr = pool.alloc(Assign.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + targets: rowptr[list[rowptr[AST]]], value: rowptr[AST]): + ptr: rowptr[Assign] = pool.alloc(Assign.__sizeof__()) if ptr: string.memset(ptr, 0, Assign.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - targets: list[AST | t.CPtr] | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + targets: rowptr[list[rowptr[AST]]], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.targets = targets self.value = value _set_parent_list(targets, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Assign def type_name(self) -> str: return "Assign" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Assign(targets=") pos = _dump_list(self.targets, buf, size, pos) @@ -88,33 +88,33 @@ class Assign(Stmt): # ============================================================ class If(Stmt): - """If(test: AST, orelse: list[AST | t.CPtr])""" - test: AST | t.CPtr - orelse: list[AST | t.CPtr] | t.CPtr + """If(test: AST, orelse: list[rowptr[AST]])""" + test: rowptr[AST] + orelse: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - test: AST | t.CPtr, - orelse: list[AST | t.CPtr] | t.CPtr): - ptr: If | t.CPtr = pool.alloc(If.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + test: rowptr[AST], + orelse: rowptr[list[rowptr[AST]]]): + ptr: rowptr[If] = pool.alloc(If.__sizeof__()) if ptr: string.memset(ptr, 0, If.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - test: AST | t.CPtr, - orelse: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + test: rowptr[AST], + orelse: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.test = test self.orelse = orelse _set_parent_list(orelse, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.If def type_name(self) -> str: return "If" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "If(test=") if self.test is not None: @@ -134,25 +134,25 @@ class If(Stmt): # ============================================================ class For(Stmt): - """For(target: AST, iter: AST, orelse: list[AST | t.CPtr], is_async: CInt)""" - target: AST | t.CPtr - iter: AST | t.CPtr - orelse: list[AST | t.CPtr] | t.CPtr - flags: t.CInt + """For(target: AST, iter: AST, orelse: list[rowptr[AST]], is_async: CInt)""" + target: rowptr[AST] + iter: rowptr[AST] + orelse: rowptr[list[rowptr[AST]]] + flags: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, iter: AST | t.CPtr, - orelse: list[AST | t.CPtr] | t.CPtr, - is_async: t.CInt): - ptr: For | t.CPtr = pool.alloc(For.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], iter: rowptr[AST], + orelse: rowptr[list[rowptr[AST]]], + is_async: int): + ptr: rowptr[For] = pool.alloc(For.__sizeof__()) if ptr: string.memset(ptr, 0, For.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, iter: AST | t.CPtr, - orelse: list[AST | t.CPtr] | t.CPtr, - is_async: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], iter: rowptr[AST], + orelse: rowptr[list[rowptr[AST]]], + is_async: int): _init_ast(self, pool, 0, 0) self.target = target self.iter = iter @@ -163,13 +163,13 @@ class For(Stmt): self.flags = 0 _set_parent_list(orelse, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.For def type_name(self) -> str: return "For" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "For(target=") if self.target is not None: @@ -192,33 +192,33 @@ class For(Stmt): # ============================================================ class While(Stmt): - """While(test: AST, orelse: list[AST | t.CPtr])""" - test: AST | t.CPtr - orelse: list[AST | t.CPtr] | t.CPtr + """While(test: AST, orelse: list[rowptr[AST]])""" + test: rowptr[AST] + orelse: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - test: AST | t.CPtr, - orelse: list[AST | t.CPtr] | t.CPtr): - ptr: While | t.CPtr = pool.alloc(While.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + test: rowptr[AST], + orelse: rowptr[list[rowptr[AST]]]): + ptr: rowptr[While] = pool.alloc(While.__sizeof__()) if ptr: string.memset(ptr, 0, While.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - test: AST | t.CPtr, - orelse: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + test: rowptr[AST], + orelse: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.test = test self.orelse = orelse _set_parent_list(orelse, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.While def type_name(self) -> str: return "While" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "While(test=") if self.test is not None: @@ -237,25 +237,25 @@ class While(Stmt): class Return(Stmt): """Return(value: AST | None)""" - value: AST | t.CPtr + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): - ptr: Return | t.CPtr = pool.alloc(Return.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): + ptr: rowptr[Return] = pool.alloc(Return.__sizeof__()) if ptr: string.memset(ptr, 0, Return.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Return def type_name(self) -> str: return "Return" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Return(value=") if self.value is not None: @@ -272,25 +272,25 @@ class Return(Stmt): class Expr(Stmt): """Expr(value: AST)""" - value: AST | t.CPtr + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): - ptr: Expr | t.CPtr = pool.alloc(Expr.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): + ptr: rowptr[Expr] = pool.alloc(Expr.__sizeof__()) if ptr: string.memset(ptr, 0, Expr.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Expr def type_name(self) -> str: return "Expr" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Expr(value=") if self.value is not None: @@ -307,32 +307,32 @@ class Expr(Stmt): class FunctionDef(Stmt): """FunctionDef(name: str, args: AST, - decorator_list: list[AST | t.CPtr], returns: AST, flags: CInt, - type_params: list[str] | t.CPtr = None) + decorator_list: list[rowptr[AST]], returns: AST, flags: CInt, + type_params: rowptr[list[str]] = None) type_params: 泛型函数类型参数名列表(PEP 695 def f[T](...): 中的 [T]), None 表示非泛型函数。""" name: str - args: AST | t.CPtr - decorator_list: list[AST | t.CPtr] | t.CPtr - returns: AST | t.CPtr - flags: t.CInt - type_params: list[str] | t.CPtr + args: rowptr[AST] + decorator_list: rowptr[list[rowptr[AST]]] + returns: rowptr[AST] + flags: int + type_params: rowptr[list[str]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - name: str, args: AST | t.CPtr, - decorator_list: list[AST | t.CPtr] | t.CPtr, - returns: AST | t.CPtr, is_async: t.CInt): - ptr: FunctionDef | t.CPtr = pool.alloc(FunctionDef.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + name: str, args: rowptr[AST], + decorator_list: rowptr[list[rowptr[AST]]], + returns: rowptr[AST], is_async: int): + ptr: rowptr[FunctionDef] = pool.alloc(FunctionDef.__sizeof__()) if ptr: string.memset(ptr, 0, FunctionDef.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - name: str, args: AST | t.CPtr, - decorator_list: list[AST | t.CPtr] | t.CPtr, - returns: AST | t.CPtr, is_async: t.CInt, - type_params: list[str] | t.CPtr = None): + def __init__(self, pool: rowptr[memhub.MemManager], + name: str, args: rowptr[AST], + decorator_list: rowptr[list[rowptr[AST]]], + returns: rowptr[AST], is_async: int, + type_params: rowptr[list[str]] = None): _init_ast(self, pool, 0, 0) self.name = _copy_str(pool, name) self.args = args @@ -345,13 +345,13 @@ class FunctionDef(Stmt): self.flags = 0 _set_parent_list(decorator_list, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.FunctionDef def type_name(self) -> str: return "FunctionDef" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "FunctionDef(name='") pos = _emit_str(buf, size, pos, self.name) @@ -379,27 +379,27 @@ class FunctionDef(Stmt): class Expression(AST): """Expression(body: AST)""" - body: AST | t.CPtr + body: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - body: AST | t.CPtr): - ptr: Expression | t.CPtr = pool.alloc(Expression.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + body: rowptr[AST]): + ptr: rowptr[Expression] = pool.alloc(Expression.__sizeof__()) if ptr: string.memset(ptr, 0, Expression.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - body: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + body: rowptr[AST]): _init_ast(self, pool, 0, 0) self.body = body - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Expression def type_name(self) -> str: return "Expression" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Expression(body=") if self.body is not None: @@ -416,27 +416,27 @@ class Expression(AST): class Interactive(AST): """Interactive(body: AST)""" - body: AST | t.CPtr + body: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - body: AST | t.CPtr): - ptr: Interactive | t.CPtr = pool.alloc(Interactive.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + body: rowptr[AST]): + ptr: rowptr[Interactive] = pool.alloc(Interactive.__sizeof__()) if ptr: string.memset(ptr, 0, Interactive.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - body: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + body: rowptr[AST]): _init_ast(self, pool, 0, 0) self.body = body - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Interactive def type_name(self) -> str: return "Interactive" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Interactive(body=") if self.body is not None: @@ -452,32 +452,32 @@ class Interactive(AST): # ============================================================ class FunctionType(AST): - """FunctionType(argtypes: list[AST | t.CPtr], returns: AST)""" - argtypes: list[AST | t.CPtr] | t.CPtr - returns: AST | t.CPtr + """FunctionType(argtypes: list[rowptr[AST]], returns: AST)""" + argtypes: rowptr[list[rowptr[AST]]] + returns: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - argtypes: list[AST | t.CPtr] | t.CPtr, - returns: AST | t.CPtr): - ptr: FunctionType | t.CPtr = pool.alloc(FunctionType.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + argtypes: rowptr[list[rowptr[AST]]], + returns: rowptr[AST]): + ptr: rowptr[FunctionType] = pool.alloc(FunctionType.__sizeof__()) if ptr: string.memset(ptr, 0, FunctionType.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - argtypes: list[AST | t.CPtr] | t.CPtr, - returns: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + argtypes: rowptr[list[rowptr[AST]]], + returns: rowptr[AST]): _init_ast(self, pool, 0, 0) self.argtypes = argtypes self.returns = returns - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.FunctionType def type_name(self) -> str: return "FunctionType" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "FunctionType(argtypes=") pos = _dump_list(self.argtypes, buf, size, pos) @@ -495,34 +495,34 @@ class FunctionType(AST): # ============================================================ class ClassDef(Stmt): - """ClassDef(name: str, bases: list[AST | t.CPtr], keywords: list[AST | t.CPtr], - decorator_list: list[AST | t.CPtr], type_params: list[str] | t.CPtr) + """ClassDef(name: str, bases: list[rowptr[AST]], keywords: list[rowptr[AST]], + decorator_list: list[rowptr[AST]], type_params: rowptr[list[str]]) type_params: 泛型类型参数名列表(PEP 695 class list[T]: 中的 [T]), None 表示非泛型类。""" name: str - bases: list[AST | t.CPtr] | t.CPtr - keywords: list[AST | t.CPtr] | t.CPtr - decorator_list: list[AST | t.CPtr] | t.CPtr - type_params: list[str] | t.CPtr + bases: rowptr[list[rowptr[AST]]] + keywords: rowptr[list[rowptr[AST]]] + decorator_list: rowptr[list[rowptr[AST]]] + type_params: rowptr[list[str]] - def __new__(self, pool: memhub.MemManager | t.CPtr, + def __new__(self, pool: rowptr[memhub.MemManager], name: str, - bases: list[AST | t.CPtr] | t.CPtr, - keywords: list[AST | t.CPtr] | t.CPtr, - decorator_list: list[AST | t.CPtr] | t.CPtr, - type_params: list[str] | t.CPtr = None): - ptr: ClassDef | t.CPtr = pool.alloc(ClassDef.__sizeof__()) + bases: rowptr[list[rowptr[AST]]], + keywords: rowptr[list[rowptr[AST]]], + decorator_list: rowptr[list[rowptr[AST]]], + type_params: rowptr[list[str]] = None): + ptr: rowptr[ClassDef] = pool.alloc(ClassDef.__sizeof__()) if ptr: string.memset(ptr, 0, ClassDef.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, + def __init__(self, pool: rowptr[memhub.MemManager], name: str, - bases: list[AST | t.CPtr] | t.CPtr, - keywords: list[AST | t.CPtr] | t.CPtr, - decorator_list: list[AST | t.CPtr] | t.CPtr, - type_params: list[str] | t.CPtr = None): + bases: rowptr[list[rowptr[AST]]], + keywords: rowptr[list[rowptr[AST]]], + decorator_list: rowptr[list[rowptr[AST]]], + type_params: rowptr[list[str]] = None): _init_ast(self, pool, 0, 0) self.name = _copy_str(pool, name) self.bases = bases @@ -531,13 +531,13 @@ class ClassDef(Stmt): self.type_params = type_params _set_parent_list(decorator_list, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.ClassDef def type_name(self) -> str: return "ClassDef" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "ClassDef(name='") pos = _emit_str(buf, size, pos, self.name) @@ -558,29 +558,29 @@ class ClassDef(Stmt): # ============================================================ class Delete(Stmt): - """Delete(targets: list[AST | t.CPtr])""" - targets: list[AST | t.CPtr] | t.CPtr + """Delete(targets: list[rowptr[AST]])""" + targets: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - targets: list[AST | t.CPtr] | t.CPtr): - ptr: Delete | t.CPtr = pool.alloc(Delete.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + targets: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Delete] = pool.alloc(Delete.__sizeof__()) if ptr: string.memset(ptr, 0, Delete.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - targets: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + targets: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.targets = targets _set_parent_list(targets, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Delete def type_name(self) -> str: return "Delete" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Delete(targets=") pos = _dump_list(self.targets, buf, size, pos) @@ -594,31 +594,31 @@ class Delete(Stmt): class AugAssign(Stmt): """AugAssign(target: AST, op: CInt, value: AST)""" - target: AST | t.CPtr - op: t.CInt - value: AST | t.CPtr + target: rowptr[AST] + op: int + value: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, op: t.CInt, value: AST | t.CPtr): - ptr: AugAssign | t.CPtr = pool.alloc(AugAssign.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], op: int, value: rowptr[AST]): + ptr: rowptr[AugAssign] = pool.alloc(AugAssign.__sizeof__()) if ptr: string.memset(ptr, 0, AugAssign.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, op: t.CInt, value: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], op: int, value: rowptr[AST]): _init_ast(self, pool, 0, 0) self.target = target self.op = op self.value = value - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.AugAssign def type_name(self) -> str: return "AugAssign" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "AugAssign(target=") if self.target is not None: @@ -642,35 +642,35 @@ class AugAssign(Stmt): class AnnAssign(Stmt): """AnnAssign(target: AST, annotation: AST, value: AST, simple: CInt)""" - target: AST | t.CPtr - annotation: AST | t.CPtr - value: AST | t.CPtr - simple: t.CInt + target: rowptr[AST] + annotation: rowptr[AST] + value: rowptr[AST] + simple: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, annotation: AST | t.CPtr, - value: AST | t.CPtr, simple: t.CInt): - ptr: AnnAssign | t.CPtr = pool.alloc(AnnAssign.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], annotation: rowptr[AST], + value: rowptr[AST], simple: int): + ptr: rowptr[AnnAssign] = pool.alloc(AnnAssign.__sizeof__()) if ptr: string.memset(ptr, 0, AnnAssign.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - target: AST | t.CPtr, annotation: AST | t.CPtr, - value: AST | t.CPtr, simple: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + target: rowptr[AST], annotation: rowptr[AST], + value: rowptr[AST], simple: int): _init_ast(self, pool, 0, 0) self.target = target self.annotation = annotation self.value = value self.simple = simple - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.AnnAssign def type_name(self) -> str: return "AnnAssign" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "AnnAssign(target=") if self.target is not None: @@ -688,7 +688,7 @@ class AnnAssign(Stmt): else: pos = _emit(buf, size, pos, "None") pos = _emit(buf, size, pos, ", simple=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.simple)) + pos = _emit_int(buf, size, pos, int64(self.simple)) pos = _emit(buf, size, pos, ")") return pos @@ -698,21 +698,21 @@ class AnnAssign(Stmt): # ============================================================ class With(Stmt): - """With(items: list[AST | t.CPtr], is_async: CInt)""" - items: list[AST | t.CPtr] | t.CPtr - flags: t.CInt + """With(items: list[rowptr[AST]], is_async: CInt)""" + items: rowptr[list[rowptr[AST]]] + flags: int - def __new__(self, pool: memhub.MemManager | t.CPtr, - items: list[AST | t.CPtr] | t.CPtr, - is_async: t.CInt): - ptr: With | t.CPtr = pool.alloc(With.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + items: rowptr[list[rowptr[AST]]], + is_async: int): + ptr: rowptr[With] = pool.alloc(With.__sizeof__()) if ptr: string.memset(ptr, 0, With.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - items: list[AST | t.CPtr] | t.CPtr, - is_async: t.CInt): + def __init__(self, pool: rowptr[memhub.MemManager], + items: rowptr[list[rowptr[AST]]], + is_async: int): _init_ast(self, pool, 0, 0) self.items = items if is_async: @@ -721,13 +721,13 @@ class With(Stmt): self.flags = 0 _set_parent_list(items, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.With def type_name(self) -> str: return "With" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "With(items=") pos = _dump_list(self.items, buf, size, pos) @@ -743,29 +743,29 @@ class With(Stmt): class Raise(Stmt): """Raise(exc: AST, cause: AST)""" - exc: AST | t.CPtr - cause: AST | t.CPtr + exc: rowptr[AST] + cause: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - exc: AST | t.CPtr, cause: AST | t.CPtr): - ptr: Raise | t.CPtr = pool.alloc(Raise.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + exc: rowptr[AST], cause: rowptr[AST]): + ptr: rowptr[Raise] = pool.alloc(Raise.__sizeof__()) if ptr: string.memset(ptr, 0, Raise.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - exc: AST | t.CPtr, cause: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + exc: rowptr[AST], cause: rowptr[AST]): _init_ast(self, pool, 0, 0) self.exc = exc self.cause = cause - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Raise def type_name(self) -> str: return "Raise" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Raise(exc=") if self.exc is not None: @@ -786,25 +786,25 @@ class Raise(Stmt): # ============================================================ class Try(Stmt): - """Try(handlers: list[AST | t.CPtr], - orelse: list[AST | t.CPtr], finalbody: list[AST | t.CPtr])""" - handlers: list[AST | t.CPtr] | t.CPtr - orelse: list[AST | t.CPtr] | t.CPtr - finalbody: list[AST | t.CPtr] | t.CPtr + """Try(handlers: list[rowptr[AST]], + orelse: list[rowptr[AST]], finalbody: list[rowptr[AST]])""" + handlers: rowptr[list[rowptr[AST]]] + orelse: rowptr[list[rowptr[AST]]] + finalbody: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - handlers: list[AST | t.CPtr] | t.CPtr, - orelse: list[AST | t.CPtr] | t.CPtr, - finalbody: list[AST | t.CPtr] | t.CPtr): - ptr: Try | t.CPtr = pool.alloc(Try.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + handlers: rowptr[list[rowptr[AST]]], + orelse: rowptr[list[rowptr[AST]]], + finalbody: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Try] = pool.alloc(Try.__sizeof__()) if ptr: string.memset(ptr, 0, Try.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - handlers: list[AST | t.CPtr] | t.CPtr, - orelse: list[AST | t.CPtr] | t.CPtr, - finalbody: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + handlers: rowptr[list[rowptr[AST]]], + orelse: rowptr[list[rowptr[AST]]], + finalbody: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.handlers = handlers self.orelse = orelse @@ -813,13 +813,13 @@ class Try(Stmt): _set_parent_list(orelse, self) _set_parent_list(finalbody, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Try def type_name(self) -> str: return "Try" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Try(body=") pos = _dump_list(self.children, buf, size, pos) @@ -839,29 +839,29 @@ class Try(Stmt): class Assert(Stmt): """Assert(test: AST, msg: AST)""" - test: AST | t.CPtr - msg: AST | t.CPtr + test: rowptr[AST] + msg: rowptr[AST] - def __new__(self, pool: memhub.MemManager | t.CPtr, - test: AST | t.CPtr, msg: AST | t.CPtr): - ptr: Assert | t.CPtr = pool.alloc(Assert.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + test: rowptr[AST], msg: rowptr[AST]): + ptr: rowptr[Assert] = pool.alloc(Assert.__sizeof__()) if ptr: string.memset(ptr, 0, Assert.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - test: AST | t.CPtr, msg: AST | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + test: rowptr[AST], msg: rowptr[AST]): _init_ast(self, pool, 0, 0) self.test = test self.msg = msg - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Assert def type_name(self) -> str: return "Assert" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Assert(test=") if self.test is not None: @@ -882,29 +882,29 @@ class Assert(Stmt): # ============================================================ class Global(Stmt): - """Global(names: list[AST | t.CPtr])""" - names: list[AST | t.CPtr] | t.CPtr + """Global(names: list[rowptr[AST]])""" + names: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - names: list[AST | t.CPtr] | t.CPtr): - ptr: Global | t.CPtr = pool.alloc(Global.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + names: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Global] = pool.alloc(Global.__sizeof__()) if ptr: string.memset(ptr, 0, Global.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - names: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + names: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.names = names _set_parent_list(names, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Global def type_name(self) -> str: return "Global" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Global(names=") pos = _dump_list(self.names, buf, size, pos) @@ -917,29 +917,29 @@ class Global(Stmt): # ============================================================ class Nonlocal(Stmt): - """Nonlocal(names: list[AST | t.CPtr])""" - names: list[AST | t.CPtr] | t.CPtr + """Nonlocal(names: list[rowptr[AST]])""" + names: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - names: list[AST | t.CPtr] | t.CPtr): - ptr: Nonlocal | t.CPtr = pool.alloc(Nonlocal.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + names: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Nonlocal] = pool.alloc(Nonlocal.__sizeof__()) if ptr: string.memset(ptr, 0, Nonlocal.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - names: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + names: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.names = names _set_parent_list(names, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Nonlocal def type_name(self) -> str: return "Nonlocal" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Nonlocal(names=") pos = _dump_list(self.names, buf, size, pos) @@ -954,22 +954,22 @@ class Nonlocal(Stmt): class Pass(Stmt): """Pass()""" - def __new__(self, pool: memhub.MemManager | t.CPtr): - ptr: Pass | t.CPtr = pool.alloc(Pass.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager]): + ptr: rowptr[Pass] = pool.alloc(Pass.__sizeof__()) if ptr: string.memset(ptr, 0, Pass.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager]): _init_ast(self, pool, 0, 0) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Pass def type_name(self) -> str: return "Pass" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Pass()") return pos @@ -982,22 +982,22 @@ class Pass(Stmt): class Break(Stmt): """Break()""" - def __new__(self, pool: memhub.MemManager | t.CPtr): - ptr: Break | t.CPtr = pool.alloc(Break.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager]): + ptr: rowptr[Break] = pool.alloc(Break.__sizeof__()) if ptr: string.memset(ptr, 0, Break.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager]): _init_ast(self, pool, 0, 0) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Break def type_name(self) -> str: return "Break" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Break()") return pos @@ -1010,22 +1010,22 @@ class Break(Stmt): class Continue(Stmt): """Continue()""" - def __new__(self, pool: memhub.MemManager | t.CPtr): - ptr: Continue | t.CPtr = pool.alloc(Continue.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager]): + ptr: rowptr[Continue] = pool.alloc(Continue.__sizeof__()) if ptr: string.memset(ptr, 0, Continue.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager]): _init_ast(self, pool, 0, 0) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Continue def type_name(self) -> str: return "Continue" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Continue()") return pos @@ -1036,29 +1036,29 @@ class Continue(Stmt): # ============================================================ class Import(Stmt): - """Import(names: list[AST | t.CPtr])""" - names: list[AST | t.CPtr] | t.CPtr + """Import(names: list[rowptr[AST]])""" + names: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - names: list[AST | t.CPtr] | t.CPtr): - ptr: Import | t.CPtr = pool.alloc(Import.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + names: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Import] = pool.alloc(Import.__sizeof__()) if ptr: string.memset(ptr, 0, Import.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - names: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + names: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.names = names _set_parent_list(names, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Import def type_name(self) -> str: return "Import" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Import(names=") pos = _dump_list(self.names, buf, size, pos) @@ -1071,44 +1071,44 @@ class Import(Stmt): # ============================================================ class ImportFrom(Stmt): - """ImportFrom(module: str, names: list[AST | t.CPtr], level: CInt)""" + """ImportFrom(module: str, names: list[rowptr[AST]], level: CInt)""" module: str - names: list[AST | t.CPtr] | t.CPtr - level: t.CInt + names: rowptr[list[rowptr[AST]]] + level: int - def __new__(self, pool: memhub.MemManager | t.CPtr, + def __new__(self, pool: rowptr[memhub.MemManager], module: str, - names: list[AST | t.CPtr] | t.CPtr, - level: t.CInt): - ptr: ImportFrom | t.CPtr = pool.alloc(ImportFrom.__sizeof__()) + names: rowptr[list[rowptr[AST]]], + level: int): + ptr: rowptr[ImportFrom] = pool.alloc(ImportFrom.__sizeof__()) if ptr: string.memset(ptr, 0, ImportFrom.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, + def __init__(self, pool: rowptr[memhub.MemManager], module: str, - names: list[AST | t.CPtr] | t.CPtr, - level: t.CInt): + names: rowptr[list[rowptr[AST]]], + level: int): _init_ast(self, pool, 0, 0) self.module = _copy_str(pool, module) self.names = names self.level = level _set_parent_list(names, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.ImportFrom def type_name(self) -> str: return "ImportFrom" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "ImportFrom(module='") pos = _emit_str(buf, size, pos, self.module) pos = _emit(buf, size, pos, "', names=") pos = _dump_list(self.names, buf, size, pos) pos = _emit(buf, size, pos, ", level=") - pos = _emit_int(buf, size, pos, t.CInt64T(self.level)) + pos = _emit_int(buf, size, pos, int64(self.level)) pos = _emit(buf, size, pos, ")") return pos @@ -1118,33 +1118,33 @@ class ImportFrom(Stmt): # ============================================================ class Match(Stmt): - """Match(subject: AST, cases: list[AST | t.CPtr])""" - subject: AST | t.CPtr - cases: list[AST | t.CPtr] | t.CPtr + """Match(subject: AST, cases: list[rowptr[AST]])""" + subject: rowptr[AST] + cases: rowptr[list[rowptr[AST]]] - def __new__(self, pool: memhub.MemManager | t.CPtr, - subject: AST | t.CPtr, - cases: list[AST | t.CPtr] | t.CPtr): - ptr: Match | t.CPtr = pool.alloc(Match.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager], + subject: rowptr[AST], + cases: rowptr[list[rowptr[AST]]]): + ptr: rowptr[Match] = pool.alloc(Match.__sizeof__()) if ptr: string.memset(ptr, 0, Match.__sizeof__()) return ptr - def __init__(self, pool: memhub.MemManager | t.CPtr, - subject: AST | t.CPtr, - cases: list[AST | t.CPtr] | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemManager], + subject: rowptr[AST], + cases: rowptr[list[rowptr[AST]]]): _init_ast(self, pool, 0, 0) self.subject = subject self.cases = cases _set_parent_list(cases, self) - def kind(self) -> t.CInt: + def kind(self) -> int: return ASTKind.Match def type_name(self) -> str: return "Match" - def dump(self, buf: t.CChar | t.CPtr, size: t.CSizeT, + def dump(self, buf: str, size: t.CSizeT, pos: t.CSizeT) -> t.CSizeT: pos = _emit(buf, size, pos, "Match(subject=") if self.subject is not None: diff --git a/ast/tokens.vp b/ast/tokens.vp index 54a316b..7fb6f83 100644 --- a/ast/tokens.vp +++ b/ast/tokens.vp @@ -81,6 +81,9 @@ class Keyword(t.CEnum): Extern: t.State # export 函数声明关键字(等价 t.CExport,裸名导出不加 SHA1 头;软判定见 _is_funcdef_kw) Export: t.State + # define 宏函数关键字(与 def 语义一致,返回注解自动追加 t.CDefine 标记 + # 为宏函数;软判定见 _is_funcdef_kw) + Define: t.State # ============================================================ @@ -144,23 +147,23 @@ class TokOp(t.CEnum): # Token stucture # ============================================================ class Token: - type: t.CInt # Token type (TokenType.EndMarker / TokenType.NewLine / TokenType.Name / ...) - op_subtype: t.CInt # Operator subtype (OP_*). Only valid when type == TokenType.Op - kw_subtype: t.CInt # Keyword subtype (KW_*). Only valid when type == TokenType.Name and it is a keyword + type: int # Token type (TokenType.EndMarker / TokenType.NewLine / TokenType.Name / ...) + op_subtype: int # Operator subtype (OP_*). Only valid when type == TokenType.Op + kw_subtype: int # Keyword subtype (KW_*). Only valid when type == TokenType.Name and it is a keyword str_val: str # Token text (NUL‑terminated, allocated from pool) - int_val: t.CInt64T # Integer value (used by TokenType.Number) - float_val: t.CDouble # Floating‑point value (used by TokenType.Number) - is_float: t.CInt # 1 = floating‑point number, 0 = integer - is_complex: t.CInt # 1 = complex number, 0 = real number - lineno: t.CInt # Starting line number - col_offset: t.CInt # Starting column offset - end_lineno: t.CInt # Ending line number - end_col_offset: t.CInt # Ending column offset - next: Token | t.CPtr # Next token in linked list + int_val: int64 # Integer value (used by TokenType.Number) + float_val: double # Floating‑point value (used by TokenType.Number) + is_float: int # 1 = floating‑point number, 0 = integer + is_complex: int # 1 = complex number, 0 = real number + lineno: int # Starting line number + col_offset: int # Starting column offset + end_lineno: int # Ending line number + end_col_offset: int # Ending column offset + next: rowptr[Token] # Next token in linked list - def __new__(self, pool: memhub.MemManager | t.CPtr): + def __new__(self, pool: rowptr[memhub.MemManager]): """Allocate zero‑initialized Token struct memory from mpool""" - ptr: Token | t.CPtr = pool.alloc(Token.__sizeof__()) + ptr: rowptr[Token] = pool.alloc(Token.__sizeof__()) if ptr: string.memset(ptr, 0, Token.__sizeof__()) return ptr @@ -172,25 +175,25 @@ class Token: # ============================================================ class KwEntry: name: str - kw_id: t.CInt - next: KwEntry | t.CPtr + kw_id: int + next: rowptr[KwEntry] - def __new__(self, pool: memhub.MemManager | t.CPtr): - ptr: KwEntry | t.CPtr = pool.alloc(KwEntry.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager]): + ptr: rowptr[KwEntry] = pool.alloc(KwEntry.__sizeof__()) if ptr: string.memset(ptr, 0, KwEntry.__sizeof__()) return ptr # Global keyword linked list head (lazy initialization) -_kw_head: KwEntry | t.CPtr = None -_kw_pool: memhub.MemManager | t.CPtr = None +_kw_head: rowptr[KwEntry] = None +_kw_pool: rowptr[memhub.MemManager] = None -def _kw_intern(pool: memhub.MemManager | t.CPtr, name: str, kw_id: t.CInt): +def _kw_intern(pool: rowptr[memhub.MemManager], name: str, kw_id: int): """Register keyword name in the linked list""" global _kw_head - entry: KwEntry | t.CPtr = KwEntry(pool) + entry: rowptr[KwEntry] = KwEntry(pool) if entry == None: return slen: t.CSizeT = string.strlen(name) buf: str = pool.alloc(slen + 1) @@ -202,9 +205,9 @@ def _kw_intern(pool: memhub.MemManager | t.CPtr, name: str, kw_id: t.CInt): _kw_head = entry -def _kw_lookup(name: str) -> t.CInt: +def _kw_lookup(name: str) -> int: """Look up keyword name in the linked list, return the kw_id (0 if not keyword)""" - cur: KwEntry | t.CPtr = _kw_head + cur: rowptr[KwEntry] = _kw_head while cur != None: if string.strcmp(cur.name, name) == 0: return cur.kw_id @@ -212,7 +215,7 @@ def _kw_lookup(name: str) -> t.CInt: return 0 -def _init_keywords(pool: memhub.MemManager | t.CPtr): +def _init_keywords(pool: rowptr[memhub.MemManager]): """Initialize keyword linked list (only once)""" global _kw_head, _kw_pool if _kw_head != None: return @@ -259,9 +262,10 @@ def _init_keywords(pool: memhub.MemManager | t.CPtr): _kw_intern(pool, "fn", Keyword.Fn) _kw_intern(pool, "fun", Keyword.Fun) _kw_intern(pool, "func", Keyword.Func) - _kw_intern(pool, "function", Keyword.Function) - _kw_intern(pool, "extern", Keyword.Extern) + _kw_intern(pool, "function", Keyword.Function) + _kw_intern(pool, "extern", Keyword.Extern) _kw_intern(pool, "export", Keyword.Export) + _kw_intern(pool, "define", Keyword.Define) # ============================================================ @@ -271,36 +275,36 @@ def _init_keywords(pool: memhub.MemManager | t.CPtr): # ============================================================ class OpEntry: name: str # Operator text (e.g. "==", "+=") - op_id: t.CInt - length: t.CInt - next: OpEntry | t.CPtr + op_id: int + length: int + next: rowptr[OpEntry] - def __new__(self, pool: memhub.MemManager | t.CPtr): - ptr: OpEntry | t.CPtr = pool.alloc(OpEntry.__sizeof__()) + def __new__(self, pool: rowptr[memhub.MemManager]): + ptr: rowptr[OpEntry] = pool.alloc(OpEntry.__sizeof__()) if ptr: string.memset(ptr, 0, OpEntry.__sizeof__()) return ptr -_op_head: OpEntry | t.CPtr = None +_op_head: rowptr[OpEntry] = None -def _op_intern(pool: memhub.MemManager | t.CPtr, name: str, op_id: t.CInt): +def _op_intern(pool: rowptr[memhub.MemManager], name: str, op_id: int): global _op_head slen: t.CSizeT = string.strlen(name) - entry: OpEntry | t.CPtr = OpEntry(pool) + entry: rowptr[OpEntry] = OpEntry(pool) if entry == None: return buf: str = pool.alloc(slen + 1) if buf == None: return string.memcpy(buf, name, slen + 1) entry.name = buf entry.op_id = op_id - entry.length = t.CInt(slen) + entry.length = int(slen) entry.next = _op_head _op_head = entry -def _init_operators(pool: memhub.MemManager | t.CPtr): +def _init_operators(pool: rowptr[memhub.MemManager]): """Initialize the operator table (register in descending length order for easy greedy matching)""" global _op_head if _op_head != None: return @@ -356,7 +360,7 @@ def _init_operators(pool: memhub.MemManager | t.CPtr): _op_intern(pool, "~", TokOp.Tilde) -def _init_tables(pool: memhub.MemManager | t.CPtr): +def _init_tables(pool: rowptr[memhub.MemManager]): """Initialize all lookup tables (idempotent)""" _init_keywords(pool) _init_operators(pool) @@ -366,10 +370,10 @@ def _init_tables(pool: memhub.MemManager | t.CPtr): # Token creation helper functions # ============================================================ -def new_token(pool: memhub.MemManager | t.CPtr, ttype: t.CInt, lineno: t.CInt, - col_offset: t.CInt) -> Token | t.CPtr: +def new_token(pool: rowptr[memhub.MemManager], ttype: int, lineno: int, + col_offset: int) -> rowptr[Token]: """Create a new empty Token and fill in fields later""" - tok: Token | t.CPtr = Token(pool) + tok: rowptr[Token] = Token(pool) if tok == None: return None tok.type = ttype tok.lineno = lineno @@ -379,7 +383,7 @@ def new_token(pool: memhub.MemManager | t.CPtr, ttype: t.CInt, lineno: t.CInt, return tok -def token_set_str(pool: memhub.MemManager | t.CPtr, tok: Token | t.CPtr, +def token_set_str(pool: rowptr[memhub.MemManager], tok: rowptr[Token], src: str, start: t.CSizeT, length: t.CSizeT): """Copy text from src[start:start + length] to token.str_val @@ -396,7 +400,7 @@ def token_set_str(pool: memhub.MemManager | t.CPtr, tok: Token | t.CPtr, tok.str_val = buf -def token_set_str_literal(pool: memhub.MemManager | t.CPtr, tok: Token | t.CPtr, +def token_set_str_literal(pool: rowptr[memhub.MemManager], tok: rowptr[Token], text: str): """Copy a C string to token.str_val""" if tok == None or text == None: return diff --git a/builtins.vp b/builtins.vp index 1fdd467..5fdf431 100644 --- a/builtins.vp +++ b/builtins.vp @@ -1,3 +1,4 @@ +import stdint as __stdint import t # ============================================================ @@ -23,3 +24,33 @@ def max(a: double, b: double) -> double: if a > b: return a return b + +# rowptr 已内置于编译器(TPC/TPV 双端),作为语法保留字,不可重定义: +# rowptr[T] 固定表示"裸指针,指向原始类型 T"(等价 t.CPtr[T])。 +size_t: t.CTypedef = t.CSizeT +int8: t.CTypedef = t.CInt8T +int16: t.CTypedef = t.CInt16T +int32: t.CTypedef = t.CInt32T +int64: t.CTypedef = t.CInt64T +uint8: t.CTypedef = t.CUInt8T +uint16: t.CTypedef = t.CUInt16T +uint32: t.CTypedef = t.CUInt32T +uint64: t.CTypedef = t.CUInt64T + +intfast8: t.CTypedef = t.CIntFast8T +intfast16: t.CTypedef = t.CIntFast16T +intfast32: t.CTypedef = t.CIntFast32T +intfast64: t.CTypedef = t.CIntFast64T +uintfast8: t.CTypedef = t.CUIntFast8T +uintfast16: t.CTypedef = t.CUIntFast16T +uintfast32: t.CTypedef = t.CUIntFast32T +uintfast64: t.CTypedef = t.CUIntFast64T + +intleast8: t.CTypedef = t.CIntLeast8T +intleast16: t.CTypedef = t.CIntLeast16T +intleast32: t.CTypedef = t.CIntLeast32T +intleast64: t.CTypedef = t.CIntLeast64T +uintleast8: t.CTypedef = t.CUIntLeast8T +uintleast16: t.CTypedef = t.CUIntLeast16T +uintleast32: t.CTypedef = t.CUIntLeast32T +uintleast64: t.CTypedef = t.CUIntLeast64T diff --git a/hashlib/__init__.vp b/hashlib/__init__.vp index 3ee2214..b895f1c 100644 --- a/hashlib/__init__.vp +++ b/hashlib/__init__.vp @@ -1,4 +1,4 @@ -from .__md5 import md5, MD5_DIGEST_LEN -from .__sha1 import sha1, SHA1_DIGEST_LEN +from .__md5 import md5, MD5_DIGEST_LEN +from .__sha1 import sha1, SHA1_DIGEST_LEN from .__sha256 import sha256, SHA256_DIGEST_LEN from .__sha512 import sha512, SHA512_DIGEST_LEN diff --git a/hashlib/__md5.vp b/hashlib/__md5.vp index 4cf5332..6449933 100644 --- a/hashlib/__md5.vp +++ b/hashlib/__md5.vp @@ -9,15 +9,15 @@ MD5_BLOCK_LEN: t.CDefine = 64 # Group block size MD5_DIGEST_LEN: t.CDefine = 16 # Digest output length # MD5 four-round nonlinear functions -def md5_F(x: t.CUInt32T, y: t.CUInt32T, z: t.CUInt32T) -> t.CUInt32T: return (x & y) | (~x & z) -def md5_G(x: t.CUInt32T, y: t.CUInt32T, z: t.CUInt32T) -> t.CUInt32T: return (x & z) | (y & ~z) -def md5_H(x: t.CUInt32T, y: t.CUInt32T, z: t.CUInt32T) -> t.CUInt32T: return x ^ y ^ z -def md5_I(x: t.CUInt32T, y: t.CUInt32T, z: t.CUInt32T) -> t.CUInt32T: return y ^ (x | ~z) +def md5_F(x: uint32, y: uint32, z: uint32) -> uint32: return (x & y) | (~x & z) +def md5_G(x: uint32, y: uint32, z: uint32) -> uint32: return (x & z) | (y & ~z) +def md5_H(x: uint32, y: uint32, z: uint32) -> uint32: return x ^ y ^ z +def md5_I(x: uint32, y: uint32, z: uint32) -> uint32: return y ^ (x | ~z) # Circular left shift -def md5_rotl(x: t.CUInt32T, n: int) -> t.CUInt32T: return (x << n) | (x >> (32 - n)) +def md5_rotl(x: uint32, n: int) -> uint32: return (x << n) | (x >> (32 - n)) # MD5 constant table -md5_T: t.CArray[t.CUInt32T, 64] = [ +md5_T: t.CArray[uint32, 64] = [ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, @@ -39,9 +39,9 @@ md5_S: t.CArray[int, 64] = [ # ============================================================ @t.Object class md5: - state: t.CArray[t.CUInt32T, 4] # 4 32-bit state registers - count: t.CUInt64T # processed bits - buf: t.CArray[t.CUInt8T, MD5_BLOCK_LEN] # Group buffer + state: t.CArray[uint32, 4] # 4 32-bit state registers + count: uint64 # processed bits + buf: t.CArray[uint8, MD5_BLOCK_LEN] # Group buffer # Initialize MD5 context def __init__(self): string.memset(self.buf, 0, MD5_BLOCK_LEN) @@ -51,34 +51,34 @@ class md5: self.state[3] = 0x10325476 self.count = 0 # MD5 single-group compression transform - def transform(self, block: t.CUInt8T | t.CPtr): - a: t.CUInt32T = self.state[0] - b: t.CUInt32T = self.state[1] - c: t.CUInt32T = self.state[2] - d: t.CUInt32T = self.state[3] - w: t.CArray[t.CUInt32T, 16] + def transform(self, block: rowptr[uint8]): + a: uint32 = self.state[0] + b: uint32 = self.state[1] + c: uint32 = self.state[2] + d: uint32 = self.state[3] + w: t.CArray[uint32, 16] # Byte order 32-bit words for i in range(16): - w[i] = ((t.CUInt32T(block[i * 4 + 0]) << 0) | - (t.CUInt32T(block[i * 4 + 1]) << 8) | - (t.CUInt32T(block[i * 4 + 2]) << 16) | - (t.CUInt32T(block[i * 4 + 3]) << 24)) + w[i] = ((uint32(block[i * 4 + 0]) << 0) | + (uint32(block[i * 4 + 1]) << 8) | + (uint32(block[i * 4 + 2]) << 16) | + (uint32(block[i * 4 + 3]) << 24)) # 4-round 51 iterations for i in range(16): - tmp: t.CUInt32T = md5_F(b, c, d) + a + md5_T[i] + w[i] + tmp: uint32 = md5_F(b, c, d) + a + md5_T[i] + w[i] a = d; d = c; c = b b += md5_rotl(tmp, md5_S[i]) # 4-round 51 iterations for i in range(16, 32): - tmp: t.CUInt32T = md5_G(b, c, d) + a + md5_T[i] + w[(5 * i + 1) % 16] + tmp: uint32 = md5_G(b, c, d) + a + md5_T[i] + w[(5 * i + 1) % 16] a = d; d = c; c = b b += md5_rotl(tmp, md5_S[i]) for i in range(32, 48): - tmp: t.CUInt32T = md5_H(b, c, d) + a + md5_T[i] + w[(3 * i + 5) % 16] + tmp: uint32 = md5_H(b, c, d) + a + md5_T[i] + w[(3 * i + 5) % 16] a = d; d = c; c = b b += md5_rotl(tmp, md5_S[i]) for i in range(48, 64): - tmp: t.CUInt32T = md5_I(b, c, d) + a + md5_T[i] + w[(7 * i + 0) % 16] + tmp: uint32 = md5_I(b, c, d) + a + md5_T[i] + w[(7 * i + 0) % 16] a = d; d = c; c = b b += md5_rotl(tmp, md5_S[i]) # Accumulate to state registers @@ -88,7 +88,7 @@ class md5: self.state[3] += d # Batch input data def update(self, s: str): - data: t.CUInt8T | t.CPtr = t.CUInt8T(s, t.CPtr) + data: rowptr[uint8] = uint8(s, t.CPtr) length: t.CSizeT = len(s) idx: t.CSizeT = self.count % MD5_BLOCK_LEN self.count += length @@ -107,7 +107,7 @@ class md5: if length > 0: string.memcpy(self.buf + idx, data, length) # End calculation, output 16-byte digest - def final(self, out: t.CArray[t.CUInt8T, MD5_DIGEST_LEN]): + def final(self, out: t.CArray[uint8, MD5_DIGEST_LEN]): idx: t.CSizeT = self.count % MD5_BLOCK_LEN # Pad 0x80 end self.buf[idx] = 0x80 @@ -120,7 +120,7 @@ class md5: # Pad 0 to end 8 bytes string.memset(self.buf + idx, 0, MD5_BLOCK_LEN - 8 - idx) # Write total bit count - bits: t.CUInt64T = self.count << 3 + bits: uint64 = self.count << 3 for i in range(8): self.buf[MD5_BLOCK_LEN - 8 + i] = (bits >> (i * 8)) & 0xFF self.transform(self.buf) diff --git a/hashlib/__sha1.vp b/hashlib/__sha1.vp index 21ecab7..efed5bd 100644 --- a/hashlib/__sha1.vp +++ b/hashlib/__sha1.vp @@ -9,18 +9,18 @@ import t, c SHA1_BLOCK_LEN: t.CDefine = 64 SHA1_DIGEST_LEN: t.CDefine = 20 -def sha1_rotl(x: t.CUInt32T, n: int) -> t.CUInt32T: return (x << n) | (x >> (32 - n)) +def sha1_rotl(x: uint32, n: int) -> uint32: return (x << n) | (x >> (32 - n)) # 3-round logical functions -def sha1_f1(b: t.CUInt32T, c: t.CUInt32T, d: t.CUInt32T) -> t.CUInt32T: return (b & c) | (~b & d) -def sha1_f2(b: t.CUInt32T, c: t.CUInt32T, d: t.CUInt32T) -> t.CUInt32T: return b ^ c ^ d -def sha1_f3(b: t.CUInt32T, c: t.CUInt32T, d: t.CUInt32T) -> t.CUInt32T: return (b & c) | (b & d) | (c & d) +def sha1_f1(b: uint32, c: uint32, d: uint32) -> uint32: return (b & c) | (~b & d) +def sha1_f2(b: uint32, c: uint32, d: uint32) -> uint32: return b ^ c ^ d +def sha1_f3(b: uint32, c: uint32, d: uint32) -> uint32: return (b & c) | (b & d) | (c & d) # SHA1 Context @t.Object class sha1: - state: t.CArray[t.CUInt32T, 5] - count: t.CUInt64T - buf: t.CArray[t.CUInt8T, SHA1_BLOCK_LEN] + state: t.CArray[uint32, 5] + count: uint64 + buf: t.CArray[uint8, SHA1_BLOCK_LEN] def __init__(self): string.memset(self.buf, 0, SHA1_BLOCK_LEN) self.state[0] = 0x67452301 @@ -30,25 +30,25 @@ class sha1: self.state[4] = 0xc3d2e1f0 self.count = 0 # Single-group compression transform - def transform(self, block: t.CUInt8T | t.CPtr): - w: t.CArray[t.CUInt32T, 80] - data: t.CUInt8T | t.CPtr = block + def transform(self, block: rowptr[uint8]): + w: t.CArray[uint32, 80] + data: rowptr[uint8] = block # First 16 words for i in range(16): - w[i] = (((t.CUInt32T(data[i * 4 + 0])) << 24) | - ((t.CUInt32T(data[i * 4 + 1])) << 16) | - ((t.CUInt32T(data[i * 4 + 2])) << 8) | - ((t.CUInt32T(data[i * 4 + 3])) << 0)) + w[i] = (((uint32(data[i * 4 + 0])) << 24) | + ((uint32(data[i * 4 + 1])) << 16) | + ((uint32(data[i * 4 + 2])) << 8) | + ((uint32(data[i * 4 + 3])) << 0)) # Extend to 80 words for i in range(16, 80): w[i] = sha1_rotl(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16],1) - a: t.CUInt32T = self.state[0] - b: t.CUInt32T = self.state[1] - c: t.CUInt32T = self.state[2] - d: t.CUInt32T = self.state[3] - e: t.CUInt32T = self.state[4] - k: t.CUInt32T - tmp: t.CUInt32T + a: uint32 = self.state[0] + b: uint32 = self.state[1] + c: uint32 = self.state[2] + d: uint32 = self.state[3] + e: uint32 = self.state[4] + k: uint32 + tmp: uint32 # 4-round iterations for i in range(0, 20): k = 0x5a827999 @@ -80,7 +80,7 @@ class sha1: self.state[3] += d self.state[4] += e def update(self, s: str): - data: t.CUInt8T | t.CPtr = t.CUInt8T(s, t.CPtr) + data: rowptr[uint8] = uint8(s, t.CPtr) length: t.CSizeT = len(s) idx: t.CSizeT = self.count % SHA1_BLOCK_LEN self.count += length @@ -98,7 +98,7 @@ class sha1: length -= SHA1_BLOCK_LEN if length > 0: string.memcpy(self.buf + idx, data, length) - def final(self, out: t.CArray[t.CUInt8T, SHA1_DIGEST_LEN]): + def final(self, out: t.CArray[uint8, SHA1_DIGEST_LEN]): idx: t.CSizeT = self.count % SHA1_BLOCK_LEN self.buf[idx] = 0x80 idx += 1 @@ -107,7 +107,7 @@ class sha1: self.transform(self.buf) idx = 0 string.memset(self.buf + idx,0,SHA1_BLOCK_LEN-8-idx) - bits: t.CUInt64T = self.count << 3 + bits: uint64 = self.count << 3 # SHA1 big-endian write length for i in range(8): self.buf[SHA1_BLOCK_LEN - 8 + i] = (bits >> (56 - i * 8)) & 0xFF diff --git a/hashlib/__sha256.vp b/hashlib/__sha256.vp index c04af58..a0b1ff8 100644 --- a/hashlib/__sha256.vp +++ b/hashlib/__sha256.vp @@ -9,7 +9,7 @@ SHA256_BLOCK_LEN: t.CDefine = 64 SHA256_DIGEST_LEN: t.CDefine = 32 # SHA256 Constants K -sha256_K: t.CArray[t.CUInt32T, 64] = [ +sha256_K: t.CArray[uint32, 64] = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, @@ -21,19 +21,19 @@ sha256_K: t.CArray[t.CUInt32T, 64] = [ ] # SHA256 Auxiliary Functions -def s0(x: t.CUInt32T) -> t.CUInt32T: return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ ((x >> 3)) -def s1(x: t.CUInt32T) -> t.CUInt32T: return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ ((x >> 10)) -def S0(x: t.CUInt32T) -> t.CUInt32T: return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)) -def S1(x: t.CUInt32T) -> t.CUInt32T: return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)) -def Ch(x: t.CUInt32T, y: t.CUInt32T, z: t.CUInt32T) -> t.CUInt32T: return (x & y) ^ (~x & z) -def Maj(x: t.CUInt32T, y: t.CUInt32T, z: t.CUInt32T) -> t.CUInt32T: return (x & y) ^ (x & z) ^ (y & z) +def s0(x: uint32) -> uint32: return ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ ((x >> 3)) +def s1(x: uint32) -> uint32: return ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ ((x >> 10)) +def S0(x: uint32) -> uint32: return ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10)) +def S1(x: uint32) -> uint32: return ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7)) +def Ch(x: uint32, y: uint32, z: uint32) -> uint32: return (x & y) ^ (~x & z) +def Maj(x: uint32, y: uint32, z: uint32) -> uint32: return (x & y) ^ (x & z) ^ (y & z) # SHA256 Context @t.Object class sha256: - state: t.CArray[t.CUInt32T, 8] - count: t.CUInt64T - buf: t.CArray[t.CUInt8T, SHA256_BLOCK_LEN] + state: t.CArray[uint32, 8] + count: uint64 + buf: t.CArray[uint8, SHA256_BLOCK_LEN] def __init__(self): string.memset(self, 0, sha256.__sizeof__()) self.state[0] = 0x6a09e667 @@ -47,26 +47,26 @@ class sha256: self.count = 0 # string.memset(self.buf, 0, SHA256_BLOCK_LEN) # SHA256 single-group compression transform - def transform(self, block: t.CUInt8T | t.CPtr): - w: t.CArray[t.CUInt32T, 64] + def transform(self, block: rowptr[uint8]): + w: t.CArray[uint32, 64] for i in range(16): - w[i] = ((t.CUInt32T(block[i * 4 + 0]) << 24) | - (t.CUInt32T(block[i * 4 + 1]) << 16) | - (t.CUInt32T(block[i * 4 + 2]) << 8 ) | - (t.CUInt32T(block[i * 4 + 3]) << 0 )) + w[i] = ((uint32(block[i * 4 + 0]) << 24) | + (uint32(block[i * 4 + 1]) << 16) | + (uint32(block[i * 4 + 2]) << 8 ) | + (uint32(block[i * 4 + 3]) << 0 )) # Extend to 64 words for i in range(16, 64): w[i] = w[i-16] + s0(w[i-15]) + w[i-7] + s1(w[i-2]) - a: t.CUInt32T = self.state[0] - b: t.CUInt32T = self.state[1] - c: t.CUInt32T = self.state[2] - d: t.CUInt32T = self.state[3] - e: t.CUInt32T = self.state[4] - f: t.CUInt32T = self.state[5] - g: t.CUInt32T = self.state[6] - h: t.CUInt32T = self.state[7] - t1: t.CUInt32T - t2: t.CUInt32T + a: uint32 = self.state[0] + b: uint32 = self.state[1] + c: uint32 = self.state[2] + d: uint32 = self.state[3] + e: uint32 = self.state[4] + f: uint32 = self.state[5] + g: uint32 = self.state[6] + h: uint32 = self.state[7] + t1: uint32 + t2: uint32 # 64-round iterations for i in range(64): t1 = h + S1(e) + Ch(e,f,g) + sha256_K[i] + w[i] @@ -85,7 +85,7 @@ class sha256: self.state[6] += g self.state[7] += h def update(self, s: str): - data: t.CUInt8T | t.CPtr = t.CUInt8T(s, t.CPtr) + data: rowptr[uint8] = uint8(s, t.CPtr) length: t.CSizeT = len(s) idx: t.CSizeT = self.count % SHA256_BLOCK_LEN self.count += length @@ -103,7 +103,7 @@ class sha256: length -= SHA256_BLOCK_LEN if length > 0: string.memcpy(self.buf + idx, data, length) - def final(self, out: t.CArray[t.CUInt8T, SHA256_DIGEST_LEN]): + def final(self, out: t.CArray[uint8, SHA256_DIGEST_LEN]): idx: t.CSizeT = self.count % SHA256_BLOCK_LEN self.buf[idx] = 0x80 idx += 1 @@ -112,7 +112,7 @@ class sha256: self.transform(self.buf) idx = 0 string.memset(self.buf + idx, 0, SHA256_BLOCK_LEN - 8 - idx) - bits: t.CUInt64T = self.count << 3 + bits: uint64 = self.count << 3 for i in range(8): self.buf[SHA256_BLOCK_LEN-8+i] = (bits >> (56 - i*8)) & 0xFF self.transform(self.buf) diff --git a/hashlib/__sha512.vp b/hashlib/__sha512.vp index cbcec85..2b33a4b 100644 --- a/hashlib/__sha512.vp +++ b/hashlib/__sha512.vp @@ -1,4 +1,4 @@ -import t, c +import t, c import string @@ -8,16 +8,16 @@ import string SHA512_BLOCK_LEN: t.CDefine = 128 SHA512_DIGEST_LEN: t.CDefine = 64 -def sha512_ror(x: t.CUInt64T, n: int) -> t.CUInt64T: return (x >> n) | (x << (64 - n)) -def sha512_shr(x: t.CUInt64T, n: int) -> t.CUInt64T: return x >> n -def sha512_Ch (x: t.CUInt64T, y: t.CUInt64T, z: t.CUInt64T) -> t.CUInt64T: return (x & y) ^ (~x & z) -def sha512_Maj(x: t.CUInt64T, y: t.CUInt64T, z: t.CUInt64T) -> t.CUInt64T: return (x & y) ^ (x & z) ^ (y & z) -def sha512_BigSigma0(x: t.CUInt64T) -> t.CUInt64T: return sha512_ror(x, 28) ^ sha512_ror(x, 34) ^ sha512_ror(x, 39) -def sha512_BigSigma1(x: t.CUInt64T) -> t.CUInt64T: return sha512_ror(x, 14) ^ sha512_ror(x, 18) ^ sha512_ror(x, 41) -def sha512_Sigma0(x: t.CUInt64T) -> t.CUInt64T: return sha512_ror(x, 1) ^ sha512_ror(x, 8) ^ sha512_shr(x, 7) -def sha512_Sigma1(x: t.CUInt64T) -> t.CUInt64T: return sha512_ror(x, 19) ^ sha512_ror(x, 61) ^ sha512_shr(x, 6) +def sha512_ror(x: uint64, n: int) -> uint64: return (x >> n) | (x << (64 - n)) +def sha512_shr(x: uint64, n: int) -> uint64: return x >> n +def sha512_Ch (x: uint64, y: uint64, z: uint64) -> uint64: return (x & y) ^ (~x & z) +def sha512_Maj(x: uint64, y: uint64, z: uint64) -> uint64: return (x & y) ^ (x & z) ^ (y & z) +def sha512_BigSigma0(x: uint64) -> uint64: return sha512_ror(x, 28) ^ sha512_ror(x, 34) ^ sha512_ror(x, 39) +def sha512_BigSigma1(x: uint64) -> uint64: return sha512_ror(x, 14) ^ sha512_ror(x, 18) ^ sha512_ror(x, 41) +def sha512_Sigma0(x: uint64) -> uint64: return sha512_ror(x, 1) ^ sha512_ror(x, 8) ^ sha512_shr(x, 7) +def sha512_Sigma1(x: uint64) -> uint64: return sha512_ror(x, 19) ^ sha512_ror(x, 61) ^ sha512_shr(x, 6) -sha512_K: t.CArray[t.CUInt64T, 80] = [ +sha512_K: t.CArray[uint64, 80] = [ 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, @@ -42,9 +42,9 @@ sha512_K: t.CArray[t.CUInt64T, 80] = [ @t.Object class sha512: - state: t.CArray[t.CUInt64T, 8] - count: t.CArray[t.CUInt64T, 2] - buf: t.CArray[t.CUInt8T, SHA512_BLOCK_LEN] + state: t.CArray[uint64, 8] + count: t.CArray[uint64, 2] + buf: t.CArray[uint8, SHA512_BLOCK_LEN] def __init__(self): string.memset(self, 0, sha512.__sizeof__()) self.state[0] = 0x6a09e667f3bcc908 @@ -55,27 +55,27 @@ class sha512: self.state[5] = 0x9b05688c2b3e6c1f self.state[6] = 0x1f83d9abfb41bd6b self.state[7] = 0x5be0cd19137e2179 - def transform(self, block: t.CArray[t.CUInt8T, SHA512_BLOCK_LEN]): - w: t.CArray[t.CUInt64T, 80] - a: t.CUInt64T - b: t.CUInt64T - c: t.CUInt64T - d: t.CUInt64T - e: t.CUInt64T - f: t.CUInt64T - g: t.CUInt64T - h: t.CUInt64T - t1: t.CUInt64T - t2: t.CUInt64T + def transform(self, block: t.CArray[uint8, SHA512_BLOCK_LEN]): + w: t.CArray[uint64, 80] + a: uint64 + b: uint64 + c: uint64 + d: uint64 + e: uint64 + f: uint64 + g: uint64 + h: uint64 + t1: uint64 + t2: uint64 for i in range(16): - w[i] = t.CUInt64T(block[i * 8 + 0]) << 56 - w[i] |= t.CUInt64T(block[i * 8 + 1]) << 48 - w[i] |= t.CUInt64T(block[i * 8 + 2]) << 40 - w[i] |= t.CUInt64T(block[i * 8 + 3]) << 32 - w[i] |= t.CUInt64T(block[i * 8 + 4]) << 24 - w[i] |= t.CUInt64T(block[i * 8 + 5]) << 16 - w[i] |= t.CUInt64T(block[i * 8 + 6]) << 8 - w[i] |= t.CUInt64T(block[i * 8 + 7]) << 0 + w[i] = uint64(block[i * 8 + 0]) << 56 + w[i] |= uint64(block[i * 8 + 1]) << 48 + w[i] |= uint64(block[i * 8 + 2]) << 40 + w[i] |= uint64(block[i * 8 + 3]) << 32 + w[i] |= uint64(block[i * 8 + 4]) << 24 + w[i] |= uint64(block[i * 8 + 5]) << 16 + w[i] |= uint64(block[i * 8 + 6]) << 8 + w[i] |= uint64(block[i * 8 + 7]) << 0 for i in range(16, 80): w[i] = sha512_Sigma1(w[i-2]) + w[i-7] + sha512_Sigma0(w[i-15]) + w[i-16] a = self.state[0] @@ -102,9 +102,9 @@ class sha512: self.state[6] += g self.state[7] += h def update(self, s: str): - data: t.CUInt8T | t.CPtr = t.CUInt8T(s, t.CPtr) + data: rowptr[uint8] = uint8(s, t.CPtr) length: t.CSizeT = len(s) - idx: t.CUInt32T = t.CUInt32T(self.count[0] % SHA512_BLOCK_LEN) + idx: uint32 = uint32(self.count[0] % SHA512_BLOCK_LEN) self.count[0] += length if self.count[0] < length: self.count[1] += 1 @@ -122,10 +122,10 @@ class sha512: length -= SHA512_BLOCK_LEN if length > 0: string.memcpy(self.buf + idx, data, length) - def final(self, out: t.CArray[t.CUInt8T, SHA512_DIGEST_LEN]): - bits_lo: t.CUInt64T = self.count[0] << 3 - bits_hi: t.CUInt64T = (self.count[1] << 3) | (self.count[0] >> 61) - idx: t.CUInt32T = t.CUInt32T(self.count[0] % SHA512_BLOCK_LEN) + def final(self, out: t.CArray[uint8, SHA512_DIGEST_LEN]): + bits_lo: uint64 = self.count[0] << 3 + bits_hi: uint64 = (self.count[1] << 3) | (self.count[0] >> 61) + idx: uint32 = uint32(self.count[0] % SHA512_BLOCK_LEN) self.buf[idx] = 0x80 idx += 1 if idx > SHA512_BLOCK_LEN - 16: @@ -134,16 +134,16 @@ class sha512: idx = 0 string.memset(self.buf + idx, 0, SHA512_BLOCK_LEN - 16 - idx) for i in range(8): - self.buf[SHA512_BLOCK_LEN - 16 + i] = t.CUInt8T(bits_hi >> (56 - i * 8)) + self.buf[SHA512_BLOCK_LEN - 16 + i] = uint8(bits_hi >> (56 - i * 8)) for i in range(8): - self.buf[SHA512_BLOCK_LEN - 8 + i] = t.CUInt8T(bits_lo >> (56 - i * 8)) + self.buf[SHA512_BLOCK_LEN - 8 + i] = uint8(bits_lo >> (56 - i * 8)) self.transform(self.buf) for i in range(8): - out[i * 8 + 0] = t.CUInt8T(self.state[i] >> 56) - out[i * 8 + 1] = t.CUInt8T(self.state[i] >> 48) - out[i * 8 + 2] = t.CUInt8T(self.state[i] >> 40) - out[i * 8 + 3] = t.CUInt8T(self.state[i] >> 32) - out[i * 8 + 4] = t.CUInt8T(self.state[i] >> 24) - out[i * 8 + 5] = t.CUInt8T(self.state[i] >> 16) - out[i * 8 + 6] = t.CUInt8T(self.state[i] >> 8) - out[i * 8 + 7] = t.CUInt8T(self.state[i] >> 0) + out[i * 8 + 0] = uint8(self.state[i] >> 56) + out[i * 8 + 1] = uint8(self.state[i] >> 48) + out[i * 8 + 2] = uint8(self.state[i] >> 40) + out[i * 8 + 3] = uint8(self.state[i] >> 32) + out[i * 8 + 4] = uint8(self.state[i] >> 24) + out[i * 8 + 5] = uint8(self.state[i] >> 16) + out[i * 8 + 6] = uint8(self.state[i] >> 8) + out[i * 8 + 7] = uint8(self.state[i] >> 0) diff --git a/json/__init__.vp b/json/__init__.vp index 49f6e23..1b93c36 100644 --- a/json/__init__.vp +++ b/json/__init__.vp @@ -23,17 +23,17 @@ JSON_OBJECT: t.CDefine = 6 class JsonValue: vtype: int bool_val: int - int_val: t.CInt64T - float_val: t.CDouble + int_val: int64 + float_val: double str_val: str next: 'JsonValue' | t.CPtr key: str child: 'JsonValue' | t.CPtr child_count: t.CSizeT - def __new__(self, pool: memhub.MemManager | t.CPtr): + def __new__(self, pool: rowptr[memhub.MemManager]): """从 mpool 分配 JsonValue 结构体内存并零初始化""" - ptr: JsonValue | t.CPtr = pool.alloc(JsonValue.__sizeof__()) + ptr: rowptr[JsonValue] = pool.alloc(JsonValue.__sizeof__()) if ptr: string.memset(ptr, 0, JsonValue.__sizeof__()) return ptr @@ -65,10 +65,10 @@ class JsonValue: def as_bool(self) -> bool: return self.bool_val != 0 - def as_int(self) -> t.CInt64T: + def as_int(self) -> int64: return self.int_val - def as_float(self) -> t.CDouble: + def as_float(self) -> double: return self.float_val def as_string(self) -> str: @@ -83,7 +83,7 @@ class JsonValue: return None if key == None: return None - cur: JsonValue | t.CPtr = self.child + cur: rowptr[JsonValue] = self.child while cur != None: if cur.key != None: if string.strcmp(cur.key, key) == 0: @@ -95,7 +95,7 @@ class JsonValue: """Python风格赋值:v["key"] = val""" if self.vtype != JSON_OBJECT or key == None or val == None: return - cur: JsonValue | t.CPtr = self.child + cur: rowptr[JsonValue] = self.child while cur != None: if cur.key != None: if string.strcmp(cur.key, key) == 0: @@ -120,7 +120,7 @@ class JsonValue: """按索引取数组元素:v.get_item(0)""" if self.vtype != JSON_ARRAY and self.vtype != JSON_OBJECT: return None - cur: JsonValue | t.CPtr = self.child + cur: rowptr[JsonValue] = self.child i: t.CSizeT = 0 while cur != None: if i == index: @@ -137,7 +137,7 @@ class JsonValue: if self.child == None: self.child = child else: - cur: JsonValue | t.CPtr = self.child + cur: rowptr[JsonValue] = self.child while cur.next != None: cur = cur.next cur.next = child @@ -148,35 +148,35 @@ class JsonValue: # 构造函数:创建各类 JsonValue(从 mpool 分配) # ============================================================ -def null(pool: memhub.MemManager | t.CPtr) -> JsonValue | t.CPtr: - v: JsonValue | t.CPtr = JsonValue(pool) +def null(pool: rowptr[memhub.MemManager]) -> rowptr[JsonValue]: + v: rowptr[JsonValue] = JsonValue(pool) if v == None: return None v.vtype = JSON_NULL return v -def bool_val(pool: memhub.MemManager | t.CPtr, val: bool) -> JsonValue | t.CPtr: - v: JsonValue | t.CPtr = JsonValue(pool) +def bool_val(pool: rowptr[memhub.MemManager], val: bool) -> rowptr[JsonValue]: + v: rowptr[JsonValue] = JsonValue(pool) if v == None: return None v.vtype = JSON_BOOL v.bool_val = 1 if val else 0 return v -def int_val(pool: memhub.MemManager | t.CPtr, val: t.CInt64T) -> JsonValue | t.CPtr: - v: JsonValue | t.CPtr = JsonValue(pool) +def int_val(pool: rowptr[memhub.MemManager], val: int64) -> rowptr[JsonValue]: + v: rowptr[JsonValue] = JsonValue(pool) if v == None: return None v.vtype = JSON_INT v.int_val = val return v -def float_val(pool: memhub.MemManager | t.CPtr, val: t.CDouble) -> JsonValue | t.CPtr: - v: JsonValue | t.CPtr = JsonValue(pool) +def float_val(pool: rowptr[memhub.MemManager], val: double) -> rowptr[JsonValue]: + v: rowptr[JsonValue] = JsonValue(pool) if v == None: return None v.vtype = JSON_FLOAT v.float_val = val return v -def string_val(pool: memhub.MemManager | t.CPtr, val: str) -> JsonValue | t.CPtr: - v: JsonValue | t.CPtr = JsonValue(pool) +def string_val(pool: rowptr[memhub.MemManager], val: str) -> rowptr[JsonValue]: + v: rowptr[JsonValue] = JsonValue(pool) if v == None: return None v.vtype = JSON_STRING if val != None: @@ -187,29 +187,29 @@ def string_val(pool: memhub.MemManager | t.CPtr, val: str) -> JsonValue | t.CPtr v.str_val = buf return v -def array(pool: memhub.MemManager | t.CPtr) -> JsonValue | t.CPtr: - v: JsonValue | t.CPtr = JsonValue(pool) +def array(pool: rowptr[memhub.MemManager]) -> rowptr[JsonValue]: + v: rowptr[JsonValue] = JsonValue(pool) if v == None: return None v.vtype = JSON_ARRAY return v -def object(pool: memhub.MemManager | t.CPtr) -> JsonValue | t.CPtr: - v: JsonValue | t.CPtr = JsonValue(pool) +def object(pool: rowptr[memhub.MemManager]) -> rowptr[JsonValue]: + v: rowptr[JsonValue] = JsonValue(pool) if v == None: return None v.vtype = JSON_OBJECT return v # 向数组追加元素 -def array_append(pool: memhub.MemManager | t.CPtr, arr: JsonValue | t.CPtr, item: JsonValue | t.CPtr): +def array_append(pool: rowptr[memhub.MemManager], arr: rowptr[JsonValue], item: rowptr[JsonValue]): if arr == None or item == None: return if arr.vtype != JSON_ARRAY: return arr._append_child(item) # 向对象设置键值对 -def object_set(pool: memhub.MemManager | t.CPtr, obj: JsonValue | t.CPtr, key: str, val: JsonValue | t.CPtr): +def object_set(pool: rowptr[memhub.MemManager], obj: rowptr[JsonValue], key: str, val: rowptr[JsonValue]): if obj == None or key == None or val == None: return if obj.vtype != JSON_OBJECT: return - cur: JsonValue | t.CPtr = obj.child + cur: rowptr[JsonValue] = obj.child while cur != None: if cur.key != None: if string.strcmp(cur.key, key) == 0: diff --git a/json/__parser.vp b/json/__parser.vp index bc6ef1f..5cf7198 100644 --- a/json/__parser.vp +++ b/json/__parser.vp @@ -13,28 +13,28 @@ class ParseState: src: str pos: t.CSizeT len: t.CSizeT - pool: memhub.MemManager | t.CPtr + pool: rowptr[memhub.MemManager] - def __init__(self, src: str, pool: memhub.MemManager | t.CPtr): + def __init__(self, src: str, pool: rowptr[memhub.MemManager]): self.src = src self.pos = 0 self.len = string.strlen(src) if src != None else 0 self.pool = pool -def _peek(s: ParseState | t.CPtr) -> t.CChar: +def _peek(s: rowptr[ParseState]) -> t.CChar: if s.pos >= s.len: return '\0' return s.src[s.pos] -def _advance(s: ParseState | t.CPtr) -> t.CChar: +def _advance(s: rowptr[ParseState]) -> t.CChar: if s.pos >= s.len: return '\0' ch: t.CChar = s.src[s.pos] s.pos += 1 return ch -def _skip_whitespace(s: ParseState | t.CPtr): +def _skip_whitespace(s: rowptr[ParseState]): while s.pos < s.len: ch: t.CChar = s.src[s.pos] if ch == ' ' or ch == '\t' or ch == '\n' or ch == '\r': @@ -42,7 +42,7 @@ def _skip_whitespace(s: ParseState | t.CPtr): else: break -def _expect(s: ParseState | t.CPtr, ch: t.CChar) -> bool: +def _expect(s: rowptr[ParseState], ch: t.CChar) -> bool: _skip_whitespace(s) if s.pos >= s.len: return False @@ -52,7 +52,7 @@ def _expect(s: ParseState | t.CPtr, ch: t.CChar) -> bool: return True -def _parse_string(s: ParseState | t.CPtr) -> str: +def _parse_string(s: rowptr[ParseState]) -> str: if _peek(s) != '"': return None _advance(s) @@ -109,7 +109,7 @@ def _parse_string(s: ParseState | t.CPtr) -> str: return buf -def _parse_number(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: +def _parse_number(s: rowptr[ParseState]) -> rowptr[JsonValue]: _skip_whitespace(s) is_float: bool = False start: t.CSizeT = s.pos @@ -158,14 +158,14 @@ def _parse_number(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: buf[num_len] = '\0' if is_float: - val: t.CDouble = string.atof(buf) + val: double = string.atof(buf) return float_val(s.pool, val) else: - ival: t.CInt64T = string.atoll(buf) + ival: int64 = string.atoll(buf) return int_val(s.pool, ival) -def _parse_value(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: +def _parse_value(s: rowptr[ParseState]) -> rowptr[JsonValue]: _skip_whitespace(s) if s.pos >= s.len: return null(s.pool) @@ -209,18 +209,18 @@ def _parse_value(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: return null(s.pool) -def _parse_array(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: +def _parse_array(s: rowptr[ParseState]) -> rowptr[JsonValue]: if not _expect(s, '['): return null(s.pool) - arr: JsonValue | t.CPtr = array(s.pool) + arr: rowptr[JsonValue] = array(s.pool) _skip_whitespace(s) if s.pos < s.len and _peek(s) == ']': _advance(s) return arr - item: JsonValue | t.CPtr = _parse_value(s) + item: rowptr[JsonValue] = _parse_value(s) arr._append_child(item) while True: @@ -237,11 +237,11 @@ def _parse_array(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: return arr -def _parse_object(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: +def _parse_object(s: rowptr[ParseState]) -> rowptr[JsonValue]: if not _expect(s, '{'): return null(s.pool) - obj: JsonValue | t.CPtr = object(s.pool) + obj: rowptr[JsonValue] = object(s.pool) _skip_whitespace(s) if s.pos < s.len and _peek(s) == '}': @@ -251,7 +251,7 @@ def _parse_object(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: _skip_whitespace(s) key: str = _parse_string(s) _expect(s, ':') - val: JsonValue | t.CPtr = _parse_value(s) + val: rowptr[JsonValue] = _parse_value(s) if key != None and val != None: klen: t.CSizeT = string.strlen(key) kbuf: str = s.pool.alloc(klen + 1) @@ -283,9 +283,9 @@ def _parse_object(s: ParseState | t.CPtr) -> JsonValue | t.CPtr: return obj -def parse(pool: memhub.MemManager | t.CPtr, src: str) -> JsonValue | t.CPtr: +def parse(pool: rowptr[memhub.MemManager], src: str) -> rowptr[JsonValue]: """解析 JSON 字符串,返回 JsonValue 树""" if src == None: return null(pool) - s: ParseState | t.CPtr = ParseState(src, pool) + s: rowptr[ParseState] = ParseState(src, pool) return _parse_value(s) diff --git a/json/__writer.vp b/json/__writer.vp index 8a493a0..8508bc3 100644 --- a/json/__writer.vp +++ b/json/__writer.vp @@ -45,7 +45,7 @@ def _write_string_escaped(buf: str, pos: t.CSizeT, s: str) -> t.CSizeT: return pos -def _write_value(buf: str, pos: t.CSizeT, val: JsonValue | t.CPtr, pool: memhub.MemManager | t.CPtr) -> t.CSizeT: +def _write_value(buf: str, pos: t.CSizeT, val: rowptr[JsonValue], pool: rowptr[memhub.MemManager]) -> t.CSizeT: if val == None: pos = _write_str(buf, pos, "null") return pos @@ -79,7 +79,7 @@ def _write_value(buf: str, pos: t.CSizeT, val: JsonValue | t.CPtr, pool: memhub. pos = _write_str(buf, pos, "[]") return pos pos = _write_char(buf, pos, '[') - cur: JsonValue | t.CPtr = val.child + cur: rowptr[JsonValue] = val.child first: bool = True while cur != None: if not first: @@ -94,7 +94,7 @@ def _write_value(buf: str, pos: t.CSizeT, val: JsonValue | t.CPtr, pool: memhub. pos = _write_str(buf, pos, "{}") return pos pos = _write_char(buf, pos, '{') - cur2: JsonValue | t.CPtr = val.child + cur2: rowptr[JsonValue] = val.child first2: bool = True while cur2 != None: if not first2: @@ -109,7 +109,7 @@ def _write_value(buf: str, pos: t.CSizeT, val: JsonValue | t.CPtr, pool: memhub. return pos -def write(pool: memhub.MemManager | t.CPtr, val: JsonValue | t.CPtr, pretty: bool) -> str: +def write(pool: rowptr[memhub.MemManager], val: rowptr[JsonValue], pretty: bool) -> str: """将 JsonValue 序列化为 JSON 字符串""" buf: str = pool.alloc(4096) if buf == None: diff --git a/linkedlist.vp b/linkedlist.vp index 770a6ee..9eda62d 100644 --- a/linkedlist.vp +++ b/linkedlist.vp @@ -1,5 +1,7 @@ import t, c from stdint import * +import stdio +import stdlib # ============================================================ @@ -334,6 +336,37 @@ class GSList[T]: """Append node to the end of the list (O(1)).""" if node is None: return + # [DBGCHAIN] 链完整性护栏(临时诊断,用后移除):抓"第一笔"写坏 + self_n: t.CUInt64T = t.CUInt64T(self) + node_n: t.CUInt64T = t.CUInt64T(node) + head_n: t.CUInt64T = 0 + if self.Head is not None: + head_n = t.CUInt64T(self.Head) + tail_n: t.CUInt64T = 0 + if self.Tail is not None: + tail_n = t.CUInt64T(self.Tail) + if self.Count == 0 and (head_n != 0 or tail_n != 0): + stdio.printf("[DBGCHAIN] 空表但 Head/Tail 非空: self=%llx head=%llx tail=%llx count=%llu node=%llx\n", + self_n, head_n, tail_n, t.CUInt64T(self.Count), node_n) + stdio.fflush(None) + stdlib.exit(1) + if self.Count > 0 and (head_n == 0 or tail_n == 0): + stdio.printf("[DBGCHAIN] 非空表但 Head/Tail 为空: self=%llx head=%llx tail=%llx count=%llu node=%llx\n", + self_n, head_n, tail_n, t.CUInt64T(self.Count), node_n) + stdio.fflush(None) + stdlib.exit(1) + if node_n != 0 and (node_n == head_n or node_n == tail_n): + stdio.printf("[DBGCHAIN] 重复 append 同一节点: self=%llx head=%llx tail=%llx count=%llu node=%llx\n", + self_n, head_n, tail_n, t.CUInt64T(self.Count), node_n) + stdio.fflush(None) + stdlib.exit(1) + if tail_n != 0: + tail_nx: T | t.CPtr = self.Tail.Next + if tail_nx is not None: + stdio.printf("[DBGCHAIN] Tail.Next 非空(尾被写过/双归属): self=%llx tail=%llx tail.Next=%llx count=%llu node=%llx\n", + self_n, tail_n, t.CUInt64T(tail_nx), t.CUInt64T(self.Count), node_n) + stdio.fflush(None) + stdlib.exit(1) node.Next = None if self.Head is None: self.Head = node diff --git a/llvmlite/__builder.vp b/llvmlite/__builder.vp index da9cfc5..0d0e4ad 100644 --- a/llvmlite/__builder.vp +++ b/llvmlite/__builder.vp @@ -30,32 +30,32 @@ from .__function import Function, BasicBlock, block_append_text, block_set_termi # ============================================================ @t.NoVTable class IRBuilder: - Pool: memhub.MemBuddy | t.CPtr # 内存池 - Func: Function | t.CPtr # 所属函数 - CurBlock: BasicBlock | t.CPtr # 当前插入点 - Counter: t.CInt # SSA 名计数器 + Pool: rowptr[memhub.MemBuddy] # 内存池 + Func: rowptr[Function] # 所属函数 + CurBlock: rowptr[BasicBlock] # 当前插入点 + Counter: int # SSA 名计数器 # ============================================================ # 内部辅助 # ============================================================ - def _alloc_ssa_name(self) -> t.CChar | t.CPtr: + def _alloc_ssa_name(self) -> str: """分配一个 SSA 名字符串 "%N" 并递增计数器""" - pool: memhub.MemBuddy | t.CPtr = self.Pool - buf: t.CChar | t.CPtr = pool.alloc(16) + pool: rowptr[memhub.MemBuddy] = self.Pool + buf: str = pool.alloc(16) if buf is None: return None viperlib.snprintf(buf, 16, "%%%d", self.Counter) self.Counter += 1 return buf - def _type_str(self, ty: LLVMType | t.CPtr) -> t.CChar | t.CPtr: + def _type_str(self, ty: rowptr[LLVMType]) -> str: """获取类型的 IR 文本(从 pool 分配 512 字节缓冲区) 注意:复杂结构体类型(如 13 方法的虚表 {i8*,i8*,...})可能超过 64 字节, 必须使用足够大的缓冲区,否则 '}' 会被截断导致 IR 语法错误。 """ - pool: memhub.MemBuddy | t.CPtr = self.Pool - buf: t.CChar | t.CPtr = pool.alloc(512) + pool: rowptr[memhub.MemBuddy] = self.Pool + buf: str = pool.alloc(512) if buf is None: return None buf[0] = '\0' TypePrint(buf, 512, ty, pool) @@ -64,7 +64,7 @@ class IRBuilder: # 变为垃圾(如 't')或为空。立即 fail-fast 终止,防止生成 # `bitcast i8* null t` 类垃圾 IR,避免 llc 报 "expected 'to' after # cast value" 后难以定位根因。 - c0: t.CInt = buf[0] + c0: int = buf[0] if c0 == 0 or (c0 != '%' and c0 != '[' and c0 != '{' and c0 != 'f' and c0 != 'd' and c0 != 'h' and c0 != 'i' and c0 != 'l' and c0 != 'm' and c0 != 'v' and c0 != '.'): @@ -75,7 +75,7 @@ class IRBuilder: return buf - def _emit(self, text: t.CChar | t.CPtr): + def _emit(self, text: str): """将指令文本追加到当前块""" if self is None or self.CurBlock is None: return block_append_text(self.Pool, self.CurBlock, text) @@ -87,14 +87,14 @@ class IRBuilder: block_set_terminated(self.CurBlock, 1) - def _build_binop(self, op: t.CChar | t.CPtr, - lhs: Value | t.CPtr, rhs: Value | t.CPtr) -> Value | t.CPtr: + def _build_binop(self, op: str, + lhs: rowptr[Value], rhs: rowptr[Value]) -> rowptr[Value]: """二元运算通用实现""" if self is None or lhs is None or rhs is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(lhs.Ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(lhs.Ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = %s %s %s, %s", name, op, ty_s, lhs.Name, rhs.Name) self._emit(line) @@ -104,7 +104,7 @@ class IRBuilder: # ============================================================ # 块定位 # ============================================================ - def position_at_end(self, block: BasicBlock | t.CPtr): + def position_at_end(self, block: rowptr[BasicBlock]): """将插入点设为 block 的末尾,并把 block 移到函数块链表末尾。 移动 block 是为了保证 BB 文本输出顺序与控制流(position)顺序一致, @@ -116,7 +116,7 @@ class IRBuilder: function_move_block_to_end(self.Func, block) - def builder_cur_block_is_terminated(self) -> t.CInt: + def builder_cur_block_is_terminated(self) -> int: """检查当前块的 IsTerminated 标志 通过 block_get_terminated 辅助函数访问,避免链式属性 @@ -131,7 +131,7 @@ class IRBuilder: # ============================================================ # 内存指令 # ============================================================ - def build_alloca(self, ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_alloca(self, ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = alloca 返回类型为 ty* 的 SSA 值(默认对齐,由后端决定)。 @@ -139,100 +139,100 @@ class IRBuilder: 因此本函数不设默认参数;需要显式对齐请用 build_alloca_aligned。 """ if self is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(ty) - line: t.CChar | t.CPtr = pool.alloc(128) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(ty) + line: str = pool.alloc(128) if line is None: return None viperlib.snprintf(line, 128, "%s = alloca %s", name, ty_s) self._emit(line) # 结果类型是 ty* - result_ty: LLVMType | t.CPtr = LLVMType.Ptr(ty) - result_ty_ptr: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + result_ty: rowptr[LLVMType] = LLVMType.Ptr(ty) + result_ty_ptr: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if result_ty_ptr is not None: string.memset(result_ty_ptr, 0, LLVMType.__sizeof__()) c.DerefAs(result_ty_ptr, result_ty) return SSAValue(pool, result_ty_ptr, name) - def build_alloca_aligned(self, ty: LLVMType | t.CPtr, - align: int) -> Value | t.CPtr: + def build_alloca_aligned(self, ty: rowptr[LLVMType], + align: int) -> rowptr[Value]: """%N = alloca , align N 返回类型为 ty* 的 SSA 值;显式指定对齐(如 va_list 24 字节缓冲区需 16 对齐)。 align 不设默认值(TPC 并行编译时 include 默认参数不预注册),调用方必须显式传入。 """ if self is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(ty) - line: t.CChar | t.CPtr = pool.alloc(128) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(ty) + line: str = pool.alloc(128) if line is None: return None viperlib.snprintf(line, 128, "%s = alloca %s, align %d", name, ty_s, align) self._emit(line) # 结果类型是 ty* - result_ty: LLVMType | t.CPtr = LLVMType.Ptr(ty) - result_ty_ptr: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + result_ty: rowptr[LLVMType] = LLVMType.Ptr(ty) + result_ty_ptr: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if result_ty_ptr is not None: string.memset(result_ty_ptr, 0, LLVMType.__sizeof__()) c.DerefAs(result_ty_ptr, result_ty) return SSAValue(pool, result_ty_ptr, name) - def build_alloca_at_entry(self, ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_alloca_at_entry(self, ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = alloca (在函数入口块生成,确保支配性) 在入口块的终止指令之前插入 alloca,避免在条件分支内生成 alloca 导致的支配性违规(Instruction does not dominate all uses)。 """ if self is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - func: Function | t.CPtr = self.Func + pool: rowptr[memhub.MemBuddy] = self.Pool + func: rowptr[Function] = self.Func if func is None or func.Blocks is None: return self.build_alloca(ty) - entry_blk: BasicBlock | t.CPtr = func.Blocks.Head + entry_blk: rowptr[BasicBlock] = func.Blocks.Head if entry_blk is None: return self.build_alloca(ty) - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(ty) - line_text: t.CChar | t.CPtr = pool.alloc(128) + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(ty) + line_text: str = pool.alloc(128) if line_text is None: return None viperlib.snprintf(line_text, 128, "%s = alloca %s", name, ty_s) # 在入口块终止指令之前插入 - block_insert_text_before_terminator(pool, entry_blk, line_text) + block_append_text(pool, entry_blk, line_text) # 结果类型是 ty* - result_ty: LLVMType | t.CPtr = LLVMType.Ptr(ty) - result_ty_ptr: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + result_ty: rowptr[LLVMType] = LLVMType.Ptr(ty) + result_ty_ptr: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if result_ty_ptr is not None: string.memset(result_ty_ptr, 0, LLVMType.__sizeof__()) c.DerefAs(result_ty_ptr, result_ty) return SSAValue(pool, result_ty_ptr, name) - def build_load(self, ty: LLVMType | t.CPtr, - ptr: Value | t.CPtr) -> Value | t.CPtr: + def build_load(self, ty: rowptr[LLVMType], + ptr: rowptr[Value]) -> rowptr[Value]: """%N = load , """ if self is None or ptr is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(ty) - ptr_ty_s: t.CChar | t.CPtr = self._type_str(ptr.Ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(ty) + ptr_ty_s: str = self._type_str(ptr.Ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = load %s, %s %s", name, ty_s, ptr_ty_s, ptr.Name) self._emit(line) return SSAValue(pool, ty, name) - def build_store(self, val: Value | t.CPtr, ptr: Value | t.CPtr): + def build_store(self, val: rowptr[Value], ptr: rowptr[Value]): """store , """ if self is None or val is None or ptr is None: return - pool: memhub.MemBuddy | t.CPtr = self.Pool - val_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - ptr_ty_s: t.CChar | t.CPtr = self._type_str(ptr.Ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + val_ty_s: str = self._type_str(val.Ty) + ptr_ty_s: str = self._type_str(ptr.Ty) + line: str = pool.alloc(256) if line is None: return viperlib.snprintf(line, 256, "store %s %s, %s %s", val_ty_s, val.Name, ptr_ty_s, ptr.Name) self._emit(line) @@ -241,80 +241,80 @@ class IRBuilder: # ============================================================ # 二元运算指令 # ============================================================ - def build_add(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_add(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = add , """ return self._build_binop("add", lhs, rhs) - def build_sub(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_sub(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = sub , """ return self._build_binop("sub", lhs, rhs) - def build_mul(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_mul(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = mul , """ return self._build_binop("mul", lhs, rhs) - def build_sdiv(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_sdiv(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = sdiv , """ return self._build_binop("sdiv", lhs, rhs) - def build_udiv(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_udiv(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = udiv , """ return self._build_binop("udiv", lhs, rhs) - def build_srem(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_srem(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = srem , """ return self._build_binop("srem", lhs, rhs) - def build_urem(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_urem(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = urem , """ return self._build_binop("urem", lhs, rhs) - def build_and(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_and(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = and , """ return self._build_binop("and", lhs, rhs) - def build_or(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_or(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = or , """ return self._build_binop("or", lhs, rhs) - def build_xor(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_xor(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = xor , """ return self._build_binop("xor", lhs, rhs) - def build_shl(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_shl(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = shl , """ return self._build_binop("shl", lhs, rhs) - def build_lshr(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_lshr(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = lshr , """ return self._build_binop("lshr", lhs, rhs) - def build_ashr(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_ashr(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = ashr , """ return self._build_binop("ashr", lhs, rhs) @@ -322,43 +322,43 @@ class IRBuilder: # ============================================================ # 浮点二元运算指令 # ============================================================ - def build_fadd(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_fadd(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = fadd , """ return self._build_binop("fadd", lhs, rhs) - def build_fsub(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_fsub(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = fsub , """ return self._build_binop("fsub", lhs, rhs) - def build_fmul(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_fmul(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = fmul , """ return self._build_binop("fmul", lhs, rhs) - def build_fdiv(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_fdiv(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = fdiv , """ return self._build_binop("fdiv", lhs, rhs) - def build_frem(self, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_frem(self, lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = frem , """ return self._build_binop("frem", lhs, rhs) - def build_fneg(self, val: Value | t.CPtr) -> Value | t.CPtr: + def build_fneg(self, val: rowptr[Value]) -> rowptr[Value]: """%N = fneg """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - line: t.CChar | t.CPtr = pool.alloc(128) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(val.Ty) + line: str = pool.alloc(128) if line is None: return None viperlib.snprintf(line, 128, "%s = fneg %s %s", name, ty_s, val.Name) self._emit(line) @@ -368,48 +368,48 @@ class IRBuilder: # ============================================================ # 比较指令 # ============================================================ - def build_icmp(self, pred: t.CInt, - lhs: Value | t.CPtr, rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_icmp(self, pred: int, + lhs: rowptr[Value], rhs: rowptr[Value]) -> rowptr[Value]: """%N = icmp , 返回类型为 i1 的 SSA 值 """ if self is None or lhs is None or rhs is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(lhs.Ty) - pred_s: t.CChar | t.CPtr = _icmp_pred_str(pred) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(lhs.Ty) + pred_s: str = _icmp_pred_str(pred) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = icmp %s %s %s, %s", name, pred_s, ty_s, lhs.Name, rhs.Name) self._emit(line) # 结果类型是 i1 - i1_ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + i1_ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if i1_ty is not None: string.memset(i1_ty, 0, LLVMType.__sizeof__()) c.DerefAs(i1_ty, LLVMType.Int(1)) return SSAValue(pool, i1_ty, name) - def build_fcmp(self, pred: t.CInt, - lhs: Value | t.CPtr, rhs: Value | t.CPtr) -> Value | t.CPtr: + def build_fcmp(self, pred: int, + lhs: rowptr[Value], rhs: rowptr[Value]) -> rowptr[Value]: """%N = fcmp , 返回类型为 i1 的 SSA 值 """ if self is None or lhs is None or rhs is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(lhs.Ty) - pred_s: t.CChar | t.CPtr = _fcmp_pred_str(pred) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(lhs.Ty) + pred_s: str = _fcmp_pred_str(pred) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = fcmp %s %s %s, %s", name, pred_s, ty_s, lhs.Name, rhs.Name) self._emit(line) # 结果类型是 i1 - i1_ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + i1_ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if i1_ty is not None: string.memset(i1_ty, 0, LLVMType.__sizeof__()) c.DerefAs(i1_ty, LLVMType.Int(1)) @@ -419,23 +419,23 @@ class IRBuilder: # ============================================================ # 终止指令 # ============================================================ - def build_br(self, target: BasicBlock | t.CPtr): + def build_br(self, target: rowptr[BasicBlock]): """br label %""" if self is None or target is None: return - pool: memhub.MemBuddy | t.CPtr = self.Pool - line: t.CChar | t.CPtr = pool.alloc(64) + pool: rowptr[memhub.MemBuddy] = self.Pool + line: str = pool.alloc(64) if line is None: return viperlib.snprintf(line, 64, "br label %%%s", target.Name) self._emit(line) self._mark_terminated() - def build_cond_br(self, cond: Value | t.CPtr, - then_blk: BasicBlock | t.CPtr, else_blk: BasicBlock | t.CPtr): + def build_cond_br(self, cond: rowptr[Value], + then_blk: rowptr[BasicBlock], else_blk: rowptr[BasicBlock]): """br i1 , label %, label %""" if self is None or cond is None or then_blk is None or else_blk is None: return - pool: memhub.MemBuddy | t.CPtr = self.Pool - line: t.CChar | t.CPtr = pool.alloc(128) + pool: rowptr[memhub.MemBuddy] = self.Pool + line: str = pool.alloc(128) if line is None: return viperlib.snprintf(line, 128, "br i1 %s, label %%%s, label %%%s", cond.Name, then_blk.Name, else_blk.Name) @@ -443,12 +443,12 @@ class IRBuilder: self._mark_terminated() - def build_ret(self, val: Value | t.CPtr): + def build_ret(self, val: rowptr[Value]): """ret """ if self is None or val is None: return - pool: memhub.MemBuddy | t.CPtr = self.Pool - ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - line: t.CChar | t.CPtr = pool.alloc(128) + pool: rowptr[memhub.MemBuddy] = self.Pool + ty_s: str = self._type_str(val.Ty) + line: str = pool.alloc(128) if line is None: return viperlib.snprintf(line, 128, "ret %s %s", ty_s, val.Name) self._emit(line) @@ -458,8 +458,8 @@ class IRBuilder: def build_ret_void(self): """ret void""" if self is None: return - pool: memhub.MemBuddy | t.CPtr = self.Pool - line: t.CChar | t.CPtr = pool.alloc(16) + pool: rowptr[memhub.MemBuddy] = self.Pool + line: str = pool.alloc(16) if line is None: return string.strcpy(line, "ret void") self._emit(line) @@ -469,10 +469,10 @@ class IRBuilder: # ============================================================ # 调用指令 # ============================================================ - def build_call(self, callee: t.CChar | t.CPtr, - args: Value | t.CPtr, arg_count: t.CInt, - ret_ty: LLVMType | t.CPtr, - is_variadic: t.CInt = 0) -> Value | t.CPtr: + def build_call(self, callee: str, + args: rowptr[Value], arg_count: int, + ret_ty: rowptr[LLVMType], + is_variadic: int = 0) -> rowptr[Value]: """%N = call @() args 是 Value 链表头,arg_count 是参数数量。 @@ -480,36 +480,36 @@ class IRBuilder: is_variadic=1 时发射函数类型签名(如 i32 (i8*, ...) @printf)。 """ if self is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool + pool: rowptr[memhub.MemBuddy] = self.Pool # 判断返回类型是否为 void - is_void: t.CInt = 0 + is_void: int = 0 match ret_ty: case LLVMType.Void(): is_void = 1 case _: is_void = 0 - name: t.CChar | t.CPtr = None + name: str = None if is_void == 0: name = self._alloc_ssa_name() - ret_ty_s: t.CChar | t.CPtr = self._type_str(ret_ty) + ret_ty_s: str = self._type_str(ret_ty) # 构建参数列表文本 + 变参函数类型签名 - args_buf: t.CChar | t.CPtr = pool.alloc(1024) + args_buf: str = pool.alloc(1024) if args_buf is None: return None args_buf[0] = '\0' - func_ty_buf: t.CChar | t.CPtr = pool.alloc(1024) + func_ty_buf: str = pool.alloc(1024) if func_ty_buf is None: return None func_ty_buf[0] = '\0' - cur: Value | t.CPtr = args - first: t.CInt = 1 + cur: rowptr[Value] = args + first: int = 1 while cur is not None: if first == 0: _append_cstr(args_buf, 1024, ", ") _append_cstr(func_ty_buf, 1024, ", ") - arg_ty_s: t.CChar | t.CPtr = self._type_str(cur.Ty) + arg_ty_s: str = self._type_str(cur.Ty) _append_cstr(args_buf, 1024, arg_ty_s) _append_cstr(args_buf, 1024, " ") if cur.Name is not None: @@ -523,7 +523,7 @@ class IRBuilder: _append_cstr(func_ty_buf, 1024, "...") # 构造带引号的 callee 名字(SHA1 前缀名含 '.' 或以数字开头需要加引号) - callee_buf: t.CChar | t.CPtr = pool.alloc(128) + callee_buf: str = pool.alloc(128) if callee_buf is None: return None callee_buf[0] = '\0' if _ll_name_needs_quote(callee) != 0: @@ -533,7 +533,7 @@ class IRBuilder: else: _append_cstr(callee_buf, 128, callee) - line: t.CChar | t.CPtr = pool.alloc(2048) + line: str = pool.alloc(2048) if line is None: return None if is_variadic == 1: if is_void == 1: @@ -557,39 +557,39 @@ class IRBuilder: # # callee_val 是函数指针 SSA 值(必须已是函数指针类型,如 i32(i8*)*) # ============================================================ - def build_call_indirect(self, callee_val: Value | t.CPtr, - args: Value | t.CPtr, arg_count: t.CInt, - ret_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_call_indirect(self, callee_val: rowptr[Value], + args: rowptr[Value], arg_count: int, + ret_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = call %callee() 间接调用:callee_val 是函数指针 SSA 值。 """ if self is None or callee_val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool + pool: rowptr[memhub.MemBuddy] = self.Pool - is_void: t.CInt = 0 + is_void: int = 0 match ret_ty: case LLVMType.Void(): is_void = 1 case _: is_void = 0 - name: t.CChar | t.CPtr = None + name: str = None if is_void == 0: name = self._alloc_ssa_name() - ret_ty_s: t.CChar | t.CPtr = self._type_str(ret_ty) + ret_ty_s: str = self._type_str(ret_ty) # 构建参数列表文本 - args_buf: t.CChar | t.CPtr = pool.alloc(1024) + args_buf: str = pool.alloc(1024) if args_buf is None: return None args_buf[0] = '\0' - cur: Value | t.CPtr = args - first: t.CInt = 1 + cur: rowptr[Value] = args + first: int = 1 while cur is not None: if first == 0: _append_cstr(args_buf, 1024, ", ") - arg_ty_s: t.CChar | t.CPtr = self._type_str(cur.Ty) + arg_ty_s: str = self._type_str(cur.Ty) _append_cstr(args_buf, 1024, arg_ty_s) _append_cstr(args_buf, 1024, " ") if cur.Name is not None: @@ -597,7 +597,7 @@ class IRBuilder: cur = cur.Next first = 0 - line: t.CChar | t.CPtr = pool.alloc(2048) + line: str = pool.alloc(2048) if line is None: return None if is_void == 1: viperlib.snprintf(line, 2048, "call %s %s(%s)", ret_ty_s, callee_val.Name, args_buf) @@ -613,94 +613,94 @@ class IRBuilder: # ============================================================ # 类型转换指令 # ============================================================ - def build_bitcast(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_bitcast(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = bitcast to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None if val.Name is None: return None viperlib.snprintf(line, 256, "%s = bitcast %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) - ret: Value | t.CPtr = SSAValue(pool, to_ty, name) + ret: rowptr[Value] = SSAValue(pool, to_ty, name) return ret - def build_sext(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_sext(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = sext to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = sext %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_trunc(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_trunc(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = trunc to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = trunc %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_zext(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_zext(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = zext to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = zext %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_ptrtoint(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_ptrtoint(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = ptrtoint to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = ptrtoint %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_inttoptr(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_inttoptr(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = inttoptr to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = inttoptr %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) @@ -710,90 +710,90 @@ class IRBuilder: # ============================================================ # 浮点转换指令 # ============================================================ - def build_fpext(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_fpext(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = fpext to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = fpext %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_fptrunc(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_fptrunc(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = fptrunc to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = fptrunc %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_fp2si(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_fp2si(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = fptosi to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = fptosi %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_si2fp(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_si2fp(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = sitofp to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = sitofp %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_fp2ui(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_fp2ui(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = fptoui to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = fptoui %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) return SSAValue(pool, to_ty, name) - def build_ui2fp(self, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + def build_ui2fp(self, val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = uitofp to """ if self is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - from_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - to_ty_s: t.CChar | t.CPtr = self._type_str(to_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + from_ty_s: str = self._type_str(val.Ty) + to_ty_s: str = self._type_str(to_ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = uitofp %s %s to %s", name, from_ty_s, val.Name, to_ty_s) self._emit(line) @@ -803,8 +803,8 @@ class IRBuilder: # ============================================================ # GEP 指令 # ============================================================ - def build_gep(self, elem_ty: LLVMType | t.CPtr, - ptr: Value | t.CPtr, idx: Value | t.CPtr) -> Value | t.CPtr: + def build_gep(self, elem_ty: rowptr[LLVMType], + ptr: rowptr[Value], idx: rowptr[Value]) -> rowptr[Value]: """%N = getelementptr , , """ if self is None or ptr is None or idx is None: return None # 防御性检查: ptr.Ty 必须是指针类型,否则 llc 报错 @@ -813,19 +813,19 @@ class IRBuilder: # 直接 GEP 会导致 llc 编译失败 if _is_ptr_type(ptr.Ty) == 0: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - elem_ty_s: t.CChar | t.CPtr = self._type_str(elem_ty) - ptr_ty_s: t.CChar | t.CPtr = self._type_str(ptr.Ty) - idx_ty_s: t.CChar | t.CPtr = self._type_str(idx.Ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + elem_ty_s: str = self._type_str(elem_ty) + ptr_ty_s: str = self._type_str(ptr.Ty) + idx_ty_s: str = self._type_str(idx.Ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = getelementptr %s, %s %s, %s %s", name, elem_ty_s, ptr_ty_s, ptr.Name, idx_ty_s, idx.Name) self._emit(line) # GEP 结果类型是 elem_ty* - result_ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + result_ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if result_ty is not None: string.memset(result_ty, 0, LLVMType.__sizeof__()) c.DerefAs(result_ty, LLVMType.Ptr(elem_ty)) @@ -835,27 +835,27 @@ class IRBuilder: # ============================================================ # build_gep_array — 数组双索引 GEP: getelementptr [N x ty], [N x ty]* %ptr, i32 0, i32 %idx # ============================================================ - def build_gep_array(self, array_ty: LLVMType | t.CPtr, - elem_ty: LLVMType | t.CPtr, - ptr: Value | t.CPtr, idx: Value | t.CPtr) -> Value | t.CPtr: + def build_gep_array(self, array_ty: rowptr[LLVMType], + elem_ty: rowptr[LLVMType], + ptr: rowptr[Value], idx: rowptr[Value]) -> rowptr[Value]: """%N = getelementptr [N x elem_ty], [N x elem_ty]* %ptr, i32 0, i32 %idx 结果类型是 elem_ty* """ if self is None or ptr is None or idx is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - array_ty_s: t.CChar | t.CPtr = self._type_str(array_ty) - ptr_ty_s: t.CChar | t.CPtr = self._type_str(ptr.Ty) - idx_ty_s: t.CChar | t.CPtr = self._type_str(idx.Ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + array_ty_s: str = self._type_str(array_ty) + ptr_ty_s: str = self._type_str(ptr.Ty) + idx_ty_s: str = self._type_str(idx.Ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = getelementptr %s, %s %s, i32 0, %s %s", name, array_ty_s, ptr_ty_s, ptr.Name, idx_ty_s, idx.Name) self._emit(line) # GEP 结果类型是 elem_ty* - result_ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + result_ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if result_ty is not None: string.memset(result_ty, 0, LLVMType.__sizeof__()) c.DerefAs(result_ty, LLVMType.Ptr(elem_ty)) @@ -865,19 +865,19 @@ class IRBuilder: # ============================================================ # build_gep_struct — 结构体字段 GEP: getelementptr struct_ty, struct_ty* %ptr, i32 0, i32 %field_idx # ============================================================ - def build_gep_struct(self, struct_ty: LLVMType | t.CPtr, - field_ty: LLVMType | t.CPtr, - ptr: Value | t.CPtr, field_idx: t.CInt) -> Value | t.CPtr: + def build_gep_struct(self, struct_ty: rowptr[LLVMType], + field_ty: rowptr[LLVMType], + ptr: rowptr[Value], field_idx: int) -> rowptr[Value]: """%N = getelementptr struct_ty, struct_ty* %ptr, i32 0, i32 %field_idx 结果类型是 field_ty* """ if self is None or ptr is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - struct_ty_s: t.CChar | t.CPtr = self._type_str(struct_ty) - ptr_ty_s: t.CChar | t.CPtr = self._type_str(ptr.Ty) - line: t.CChar | t.CPtr = pool.alloc(2048) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + struct_ty_s: str = self._type_str(struct_ty) + ptr_ty_s: str = self._type_str(ptr.Ty) + line: str = pool.alloc(2048) if line is None: stdio.printf("[BGS] line alloc None\n") return None @@ -886,13 +886,13 @@ class IRBuilder: self._emit(line) # GEP 结果类型是 field_ty* - result_ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + result_ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if result_ty is None: stdio.printf("[BGS] result_ty alloc None\n") else: string.memset(result_ty, 0, LLVMType.__sizeof__()) c.DerefAs(result_ty, LLVMType.Ptr(field_ty)) - rv: Value | t.CPtr = SSAValue(pool, result_ty, name) + rv: rowptr[Value] = SSAValue(pool, result_ty, name) if rv is None: stdio.printf("[BGS] SSAValue None\n") return rv @@ -901,45 +901,45 @@ class IRBuilder: # ============================================================ # Phi 指令 # ============================================================ - def build_phi(self, ty: LLVMType | t.CPtr, - incoming_head: PhiIncoming | t.CPtr, count: t.CInt) -> Value | t.CPtr: + def build_phi(self, ty: rowptr[LLVMType], + incoming_head: rowptr[PhiIncoming], count: int) -> rowptr[Value]: """%N = phi [val1, %blk1], [val2, %blk2], ... incoming_head 是 PhiIncoming 链表头,count 是入边数量。 """ if self is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(ty) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(ty) # 构建入边列表文本: [val, %blk], [val, %blk], ... # 入边可能很多(如 30+ 个 or 链的 bool.merge),需要大缓冲区 - parts: t.CChar | t.CPtr = pool.alloc(4096) + parts: str = pool.alloc(4096) if parts is None: return None parts[0] = '\0' - cur: PhiIncoming | t.CPtr = incoming_head - first: t.CInt = 1 + cur: rowptr[PhiIncoming] = incoming_head + first: int = 1 while cur is not None: if first == 0: _append_cstr(parts, 4096, ", ") _append_cstr(parts, 4096, "[") # 使用中间变量避免链式结构体成员访问被编译器丢弃 - inc_val: Value | t.CPtr = cur.Val + inc_val: rowptr[Value] = cur.Val if inc_val is not None: - inc_val_name: t.CChar | t.CPtr = inc_val.Name + inc_val_name: str = inc_val.Name if inc_val_name is not None: _append_cstr(parts, 4096, inc_val_name) _append_cstr(parts, 4096, ", %") - inc_blk: BasicBlock | t.CPtr = cur.Block + inc_blk: rowptr[BasicBlock] = cur.Block if inc_blk is not None: - inc_blk_name: t.CChar | t.CPtr = inc_blk.Name + inc_blk_name: str = inc_blk.Name if inc_blk_name is not None: _append_cstr(parts, 4096, inc_blk_name) _append_cstr(parts, 4096, "]") cur = cur.Next first = 0 - line: t.CChar | t.CPtr = pool.alloc(8192) + line: str = pool.alloc(8192) if line is None: return None viperlib.snprintf(line, 8192, "%s = phi %s %s", name, ty_s, parts) self._emit(line) @@ -949,16 +949,16 @@ class IRBuilder: # ============================================================ # Switch 指令 # ============================================================ - def build_switch(self, val: Value | t.CPtr, - default_blk: BasicBlock | t.CPtr, - cases_head: SwitchCase | t.CPtr, case_count: t.CInt): + def build_switch(self, val: rowptr[Value], + default_blk: rowptr[BasicBlock], + cases_head: rowptr[SwitchCase], case_count: int): """switch , label % [, label % ...]""" if self is None or val is None or default_blk is None: return - pool: memhub.MemBuddy | t.CPtr = self.Pool - ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) + pool: rowptr[memhub.MemBuddy] = self.Pool + ty_s: str = self._type_str(val.Ty) # 构建主体: switch , label %default - line: t.CChar | t.CPtr = pool.alloc(512) + line: str = pool.alloc(512) if line is None: return viperlib.snprintf(line, 512, "switch %s %s, label %%%s", ty_s, val.Name, default_blk.Name) @@ -966,17 +966,17 @@ class IRBuilder: _append_cstr(line, 512, "\n") # 遍历 case 列表 - cur: SwitchCase | t.CPtr = cases_head - case_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) + cur: rowptr[SwitchCase] = cases_head + case_ty_s: str = self._type_str(val.Ty) while cur is not None: - case_line: t.CChar | t.CPtr = pool.alloc(128) + case_line: str = pool.alloc(128) if case_line is not None: # 使用中间变量避免链式结构体成员访问被编译器丢弃 - cv: Value | t.CPtr = cur.CaseVal - cb: BasicBlock | t.CPtr = cur.Block + cv: rowptr[Value] = cur.CaseVal + cb: rowptr[BasicBlock] = cur.Block if cv is not None and cb is not None: - cv_name: t.CChar | t.CPtr = cv.Name - cb_name: t.CChar | t.CPtr = cb.Name + cv_name: str = cv.Name + cb_name: str = cb.Name if cv_name is not None and cb_name is not None: viperlib.snprintf(case_line, 128, " %s %s, label %%%s\n", case_ty_s, cv_name, cb_name) @@ -991,14 +991,14 @@ class IRBuilder: # ============================================================ # Select 指令 # ============================================================ - def build_select(self, cond: Value | t.CPtr, - true_val: Value | t.CPtr, false_val: Value | t.CPtr) -> Value | t.CPtr: + def build_select(self, cond: rowptr[Value], + true_val: rowptr[Value], false_val: rowptr[Value]) -> rowptr[Value]: """%N = select i1 , , """ if self is None or cond is None or true_val is None or false_val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ty_s: t.CChar | t.CPtr = self._type_str(true_val.Ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ty_s: str = self._type_str(true_val.Ty) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = select i1 %s, %s %s, %s %s", name, cond.Name, ty_s, true_val.Name, ty_s, false_val.Name) @@ -1012,8 +1012,8 @@ class IRBuilder: def build_unreachable(self): """unreachable""" if self is None: return - pool: memhub.MemBuddy | t.CPtr = self.Pool - line: t.CChar | t.CPtr = pool.alloc(16) + pool: rowptr[memhub.MemBuddy] = self.Pool + line: str = pool.alloc(16) if line is None: return string.strcpy(line, "unreachable") self._emit(line) @@ -1023,18 +1023,18 @@ class IRBuilder: # ============================================================ # 原子指令 (Phase 3) # ============================================================ - def build_atomicrmw(self, op: t.CInt, - ptr: Value | t.CPtr, val: Value | t.CPtr, - order: t.CInt) -> Value | t.CPtr: + def build_atomicrmw(self, op: int, + ptr: rowptr[Value], val: rowptr[Value], + order: int) -> rowptr[Value]: """%N = atomicrmw , """ if self is None or ptr is None or val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ptr_ty_s: t.CChar | t.CPtr = self._type_str(ptr.Ty) - val_ty_s: t.CChar | t.CPtr = self._type_str(val.Ty) - op_s: t.CChar | t.CPtr = _atomic_op_str(op) - ord_s: t.CChar | t.CPtr = _atomic_order_str(order) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ptr_ty_s: str = self._type_str(ptr.Ty) + val_ty_s: str = self._type_str(val.Ty) + op_s: str = _atomic_op_str(op) + ord_s: str = _atomic_order_str(order) + line: str = pool.alloc(256) if line is None: return None viperlib.snprintf(line, 256, "%s = atomicrmw %s %s %s, %s %s %s", name, op_s, ptr_ty_s, ptr.Name, val_ty_s, val.Name, ord_s) @@ -1042,22 +1042,22 @@ class IRBuilder: return SSAValue(pool, val.Ty, name) - def build_cmpxchg(self, ptr: Value | t.CPtr, - cmp_val: Value | t.CPtr, new_val: Value | t.CPtr, - succ_order: t.CInt, fail_order: t.CInt) -> Value | t.CPtr: + def build_cmpxchg(self, ptr: rowptr[Value], + cmp_val: rowptr[Value], new_val: rowptr[Value], + succ_order: int, fail_order: int) -> rowptr[Value]: """%N = cmpxchg , , 返回 {, i1} 类型的 SSA 值(简化为返回 i64 表示的值对) """ if self is None or ptr is None or cmp_val is None or new_val is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - ptr_ty_s: t.CChar | t.CPtr = self._type_str(ptr.Ty) - cmp_ty_s: t.CChar | t.CPtr = self._type_str(cmp_val.Ty) - new_ty_s: t.CChar | t.CPtr = self._type_str(new_val.Ty) - succ_s: t.CChar | t.CPtr = _atomic_order_str(succ_order) - fail_s: t.CChar | t.CPtr = _atomic_order_str(fail_order) - line: t.CChar | t.CPtr = pool.alloc(384) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + ptr_ty_s: str = self._type_str(ptr.Ty) + cmp_ty_s: str = self._type_str(cmp_val.Ty) + new_ty_s: str = self._type_str(new_val.Ty) + succ_s: str = _atomic_order_str(succ_order) + fail_s: str = _atomic_order_str(fail_order) + line: str = pool.alloc(384) if line is None: return None viperlib.snprintf(line, 384, "%s = cmpxchg %s %s, %s %s, %s %s %s %s", name, ptr_ty_s, ptr.Name, cmp_ty_s, cmp_val.Name, @@ -1071,16 +1071,16 @@ class IRBuilder: # va_arg 指令: 从 va_list 读取下一个变长参数 # ============================================================ def build_va_arg(self, - va_list_ptr: Value | t.CPtr, - arg_ty: LLVMType | t.CPtr) -> Value | t.CPtr: + va_list_ptr: rowptr[Value], + arg_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = va_arg , """ if self is None or va_list_ptr is None or arg_ty is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool - name: t.CChar | t.CPtr = self._alloc_ssa_name() - va_list_ty_s: t.CChar | t.CPtr = self._type_str(va_list_ptr.Ty) - arg_ty_s: t.CChar | t.CPtr = self._type_str(arg_ty) - line: t.CChar | t.CPtr = pool.alloc(256) + pool: rowptr[memhub.MemBuddy] = self.Pool + name: str = self._alloc_ssa_name() + va_list_ty_s: str = self._type_str(va_list_ptr.Ty) + arg_ty_s: str = self._type_str(arg_ty) + line: str = pool.alloc(256) if line is None: return None if va_list_ptr.Name is None: return None @@ -1093,30 +1093,30 @@ class IRBuilder: # ============================================================ # 内联汇编 (Phase 3) # ============================================================ - def build_inline_asm(self, ret_ty: LLVMType | t.CPtr, - asm_text: t.CChar | t.CPtr, constraints: t.CChar | t.CPtr, - has_side_effects: t.CInt) -> Value | t.CPtr: + def build_inline_asm(self, ret_ty: rowptr[LLVMType], + asm_text: str, constraints: str, + has_side_effects: int) -> rowptr[Value]: """%N = call asm [sideeffect] "" ""() 简化的内联汇编调用,无参数版本。 """ if self is None: return None - pool: memhub.MemBuddy | t.CPtr = self.Pool + pool: rowptr[memhub.MemBuddy] = self.Pool # 判断返回类型是否为 void - is_void: t.CInt = 0 + is_void: int = 0 match ret_ty: case LLVMType.Void(): is_void = 1 case _: is_void = 0 - name: t.CChar | t.CPtr = None + name: str = None if is_void == 0: name = self._alloc_ssa_name() - ret_ty_s: t.CChar | t.CPtr = self._type_str(ret_ty) - line: t.CChar | t.CPtr = pool.alloc(512) + ret_ty_s: str = self._type_str(ret_ty) + line: str = pool.alloc(512) if line is None: return None if has_side_effects != 0: @@ -1146,9 +1146,9 @@ class IRBuilder: # IRBuilder 硬编码大小: Pool(8) + Func(8) + CurBlock(8) + Counter(4) = 32 字节 BUILDER_SIZE: t.CDefine = 32 -def new_builder(pool: memhub.MemBuddy | t.CPtr, func: Function | t.CPtr) -> IRBuilder | t.CPtr: +def new_builder(pool: rowptr[memhub.MemBuddy], func: rowptr[Function]) -> rowptr[IRBuilder]: """创建 IRBuilder,关联到函数 func""" - ptr: IRBuilder | t.CPtr = pool.alloc(BUILDER_SIZE) + ptr: rowptr[IRBuilder] = pool.alloc(BUILDER_SIZE) if ptr is None: return None string.memset(ptr, 0, BUILDER_SIZE) ptr.Pool = pool @@ -1161,7 +1161,7 @@ def new_builder(pool: memhub.MemBuddy | t.CPtr, func: Function | t.CPtr) -> IRBu # ============================================================ # 块定位 # ============================================================ -def position_at_end(builder: IRBuilder | t.CPtr, block: BasicBlock | t.CPtr): +def position_at_end(builder: rowptr[IRBuilder], block: rowptr[BasicBlock]): """将插入点设为 block 的末尾,并把 block 移到函数块链表末尾。 移动 block 是为了保证 BB 文本输出顺序与控制流(position)顺序一致, @@ -1173,12 +1173,12 @@ def position_at_end(builder: IRBuilder | t.CPtr, block: BasicBlock | t.CPtr): # ============================================================ # 内部辅助 # ============================================================ -def _alloc_ssa_name(builder: IRBuilder | t.CPtr) -> t.CChar | t.CPtr: +def _alloc_ssa_name(builder: rowptr[IRBuilder]) -> str: """分配一个 SSA 名字符串 "%N" 并递增计数器""" return builder._alloc_ssa_name() -def _type_str(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr) -> t.CChar | t.CPtr: +def _type_str(builder: rowptr[IRBuilder], ty: rowptr[LLVMType]) -> str: """获取类型的 IR 文本(从 pool 分配 512 字节缓冲区) 注意:复杂结构体类型(如 13 方法的虚表 {i8*,i8*,...})可能超过 64 字节, @@ -1187,17 +1187,17 @@ def _type_str(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr) -> t.CChar | t return builder._type_str(ty) -def _emit(builder: IRBuilder | t.CPtr, text: t.CChar | t.CPtr): +def _emit(builder: rowptr[IRBuilder], text: str): """将指令文本追加到当前块""" builder._emit(text) -def _mark_terminated(builder: IRBuilder | t.CPtr): +def _mark_terminated(builder: rowptr[IRBuilder]): """标记当前块已终止""" builder._mark_terminated() -def builder_cur_block_is_terminated(builder: IRBuilder | t.CPtr) -> t.CInt: +def builder_cur_block_is_terminated(builder: rowptr[IRBuilder]) -> int: """检查当前块的 IsTerminated 标志 通过 block_get_terminated 辅助函数访问,避免链式属性 @@ -1210,7 +1210,7 @@ def builder_cur_block_is_terminated(builder: IRBuilder | t.CPtr) -> t.CInt: # ============================================================ # 内存指令 # ============================================================ -def build_alloca(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_alloca(builder: rowptr[IRBuilder], ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = alloca 返回类型为 ty* 的 SSA 值(默认对齐,由后端决定)。 @@ -1220,8 +1220,8 @@ def build_alloca(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr) -> Value | return builder.build_alloca(ty) -def build_alloca_aligned(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr, - align: int) -> Value | t.CPtr: +def build_alloca_aligned(builder: rowptr[IRBuilder], ty: rowptr[LLVMType], + align: int) -> rowptr[Value]: """%N = alloca , align N 返回类型为 ty* 的 SSA 值;显式指定对齐(如 va_list 24 字节缓冲区需 16 对齐)。 @@ -1230,7 +1230,7 @@ def build_alloca_aligned(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr, return builder.build_alloca_aligned(ty, align) -def build_alloca_at_entry(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_alloca_at_entry(builder: rowptr[IRBuilder], ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = alloca (在函数入口块生成,确保支配性) 在入口块的终止指令之前插入 alloca,避免在条件分支内生成 alloca @@ -1239,13 +1239,13 @@ def build_alloca_at_entry(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr) -> return builder.build_alloca_at_entry(ty) -def build_load(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr, - ptr: Value | t.CPtr) -> Value | t.CPtr: +def build_load(builder: rowptr[IRBuilder], ty: rowptr[LLVMType], + ptr: rowptr[Value]) -> rowptr[Value]: """%N = load , """ return builder.build_load(ty, ptr) -def build_store(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, ptr: Value | t.CPtr): +def build_store(builder: rowptr[IRBuilder], val: rowptr[Value], ptr: rowptr[Value]): """store , """ builder.build_store(val, ptr) @@ -1253,80 +1253,80 @@ def build_store(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, ptr: Value | t # ============================================================ # 二元运算指令 # ============================================================ -def build_add(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_add(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = add , """ return builder.build_add(lhs, rhs) -def build_sub(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_sub(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = sub , """ return builder.build_sub(lhs, rhs) -def build_mul(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_mul(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = mul , """ return builder.build_mul(lhs, rhs) -def build_sdiv(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_sdiv(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = sdiv , """ return builder.build_sdiv(lhs, rhs) -def build_udiv(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_udiv(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = udiv , """ return builder.build_udiv(lhs, rhs) -def build_srem(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_srem(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = srem , """ return builder.build_srem(lhs, rhs) -def build_urem(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_urem(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = urem , """ return builder.build_urem(lhs, rhs) -def build_and(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_and(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = and , """ return builder.build_and(lhs, rhs) -def build_or(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_or(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = or , """ return builder.build_or(lhs, rhs) -def build_xor(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_xor(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = xor , """ return builder.build_xor(lhs, rhs) -def build_shl(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_shl(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = shl , """ return builder.build_shl(lhs, rhs) -def build_lshr(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_lshr(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = lshr , """ return builder.build_lshr(lhs, rhs) -def build_ashr(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_ashr(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = ashr , """ return builder.build_ashr(lhs, rhs) @@ -1334,43 +1334,43 @@ def build_ashr(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, # ============================================================ # 浮点二元运算指令 # ============================================================ -def build_fadd(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_fadd(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = fadd , """ return builder.build_fadd(lhs, rhs) -def build_fsub(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_fsub(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = fsub , """ return builder.build_fsub(lhs, rhs) -def build_fmul(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_fmul(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = fmul , """ return builder.build_fmul(lhs, rhs) -def build_fdiv(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_fdiv(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = fdiv , """ return builder.build_fdiv(lhs, rhs) -def build_frem(builder: IRBuilder | t.CPtr, lhs: Value | t.CPtr, - rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_frem(builder: rowptr[IRBuilder], lhs: rowptr[Value], + rhs: rowptr[Value]) -> rowptr[Value]: """%N = frem , """ return builder.build_frem(lhs, rhs) -def build_fneg(builder: IRBuilder | t.CPtr, val: Value | t.CPtr) -> Value | t.CPtr: +def build_fneg(builder: rowptr[IRBuilder], val: rowptr[Value]) -> rowptr[Value]: """%N = fneg """ return builder.build_fneg(val) -def _build_binop(builder: IRBuilder | t.CPtr, op: t.CChar | t.CPtr, - lhs: Value | t.CPtr, rhs: Value | t.CPtr) -> Value | t.CPtr: +def _build_binop(builder: rowptr[IRBuilder], op: str, + lhs: rowptr[Value], rhs: rowptr[Value]) -> rowptr[Value]: """二元运算通用实现""" return builder._build_binop(op, lhs, rhs) @@ -1409,7 +1409,7 @@ FCMP_UNE: t.CDefine = 14 FCMP_TRUE: t.CDefine = 15 -def _icmp_pred_str(pred: t.CInt) -> t.CChar | t.CPtr: +def _icmp_pred_str(pred: int) -> str: if pred == ICMP_EQ: return "eq" if pred == ICMP_NE: return "ne" if pred == ICMP_SGT: return "sgt" @@ -1423,7 +1423,7 @@ def _icmp_pred_str(pred: t.CInt) -> t.CChar | t.CPtr: return "eq" -def _fcmp_pred_str(pred: t.CInt) -> t.CChar | t.CPtr: +def _fcmp_pred_str(pred: int) -> str: if pred == FCMP_FALSE: return "false" if pred == FCMP_OEQ: return "oeq" if pred == FCMP_OGT: return "ogt" @@ -1443,8 +1443,8 @@ def _fcmp_pred_str(pred: t.CInt) -> t.CChar | t.CPtr: return "oeq" -def build_icmp(builder: IRBuilder | t.CPtr, pred: t.CInt, - lhs: Value | t.CPtr, rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_icmp(builder: rowptr[IRBuilder], pred: int, + lhs: rowptr[Value], rhs: rowptr[Value]) -> rowptr[Value]: """%N = icmp , 返回类型为 i1 的 SSA 值 @@ -1452,8 +1452,8 @@ def build_icmp(builder: IRBuilder | t.CPtr, pred: t.CInt, return builder.build_icmp(pred, lhs, rhs) -def build_fcmp(builder: IRBuilder | t.CPtr, pred: t.CInt, - lhs: Value | t.CPtr, rhs: Value | t.CPtr) -> Value | t.CPtr: +def build_fcmp(builder: rowptr[IRBuilder], pred: int, + lhs: rowptr[Value], rhs: rowptr[Value]) -> rowptr[Value]: """%N = fcmp , 返回类型为 i1 的 SSA 值 @@ -1464,23 +1464,23 @@ def build_fcmp(builder: IRBuilder | t.CPtr, pred: t.CInt, # ============================================================ # 终止指令 # ============================================================ -def build_br(builder: IRBuilder | t.CPtr, target: BasicBlock | t.CPtr): +def build_br(builder: rowptr[IRBuilder], target: rowptr[BasicBlock]): """br label %""" builder.build_br(target) -def build_cond_br(builder: IRBuilder | t.CPtr, cond: Value | t.CPtr, - then_blk: BasicBlock | t.CPtr, else_blk: BasicBlock | t.CPtr): +def build_cond_br(builder: rowptr[IRBuilder], cond: rowptr[Value], + then_blk: rowptr[BasicBlock], else_blk: rowptr[BasicBlock]): """br i1 , label %, label %""" builder.build_cond_br(cond, then_blk, else_blk) -def build_ret(builder: IRBuilder | t.CPtr, val: Value | t.CPtr): +def build_ret(builder: rowptr[IRBuilder], val: rowptr[Value]): """ret """ builder.build_ret(val) -def build_ret_void(builder: IRBuilder | t.CPtr): +def build_ret_void(builder: rowptr[IRBuilder]): """ret void""" builder.build_ret_void() @@ -1488,10 +1488,10 @@ def build_ret_void(builder: IRBuilder | t.CPtr): # ============================================================ # 调用指令 # ============================================================ -def build_call(builder: IRBuilder | t.CPtr, callee: t.CChar | t.CPtr, - args: Value | t.CPtr, arg_count: t.CInt, - ret_ty: LLVMType | t.CPtr, - is_variadic: t.CInt = 0) -> Value | t.CPtr: +def build_call(builder: rowptr[IRBuilder], callee: str, + args: rowptr[Value], arg_count: int, + ret_ty: rowptr[LLVMType], + is_variadic: int = 0) -> rowptr[Value]: """%N = call @() args 是 Value 链表头,arg_count 是参数数量。 @@ -1506,9 +1506,9 @@ def build_call(builder: IRBuilder | t.CPtr, callee: t.CChar | t.CPtr, # # callee_val 是函数指针 SSA 值(必须已是函数指针类型,如 i32(i8*)*) # ============================================================ -def build_call_indirect(builder: IRBuilder | t.CPtr, callee_val: Value | t.CPtr, - args: Value | t.CPtr, arg_count: t.CInt, - ret_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_call_indirect(builder: rowptr[IRBuilder], callee_val: rowptr[Value], + args: rowptr[Value], arg_count: int, + ret_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = call %callee() 间接调用:callee_val 是函数指针 SSA 值。 @@ -1519,38 +1519,38 @@ def build_call_indirect(builder: IRBuilder | t.CPtr, callee_val: Value | t.CPtr, # ============================================================ # 类型转换指令 # ============================================================ -def build_bitcast(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_bitcast(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = bitcast to """ return builder.build_bitcast(val, to_ty) -def build_sext(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_sext(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = sext to """ return builder.build_sext(val, to_ty) -def build_trunc(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_trunc(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = trunc to """ return builder.build_trunc(val, to_ty) -def build_zext(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_zext(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = zext to """ return builder.build_zext(val, to_ty) -def build_ptrtoint(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_ptrtoint(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = ptrtoint to """ return builder.build_ptrtoint(val, to_ty) -def build_inttoptr(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_inttoptr(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = inttoptr to """ return builder.build_inttoptr(val, to_ty) @@ -1558,38 +1558,38 @@ def build_inttoptr(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, # ============================================================ # 浮点转换指令 # ============================================================ -def build_fpext(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_fpext(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = fpext to """ return builder.build_fpext(val, to_ty) -def build_fptrunc(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_fptrunc(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = fptrunc to """ return builder.build_fptrunc(val, to_ty) -def build_fp2si(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_fp2si(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = fptosi to """ return builder.build_fp2si(val, to_ty) -def build_si2fp(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_si2fp(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = sitofp to """ return builder.build_si2fp(val, to_ty) -def build_fp2ui(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_fp2ui(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = fptoui to """ return builder.build_fp2ui(val, to_ty) -def build_ui2fp(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - to_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_ui2fp(builder: rowptr[IRBuilder], val: rowptr[Value], + to_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = uitofp to """ return builder.build_ui2fp(val, to_ty) @@ -1597,7 +1597,7 @@ def build_ui2fp(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, # ============================================================ # GEP 指令 # ============================================================ -def _is_ptr_type(ty: LLVMType | t.CPtr) -> int: +def _is_ptr_type(ty: rowptr[LLVMType]) -> int: """检查 ty 是否是 Ptr 类型(独立函数,避免嵌套 match 的编译器 BUG)""" if ty is None: return 0 @@ -1608,8 +1608,8 @@ def _is_ptr_type(ty: LLVMType | t.CPtr) -> int: return 0 -def build_gep(builder: IRBuilder | t.CPtr, elem_ty: LLVMType | t.CPtr, - ptr: Value | t.CPtr, idx: Value | t.CPtr) -> Value | t.CPtr: +def build_gep(builder: rowptr[IRBuilder], elem_ty: rowptr[LLVMType], + ptr: rowptr[Value], idx: rowptr[Value]) -> rowptr[Value]: """%N = getelementptr , , """ return builder.build_gep(elem_ty, ptr, idx) @@ -1617,9 +1617,9 @@ def build_gep(builder: IRBuilder | t.CPtr, elem_ty: LLVMType | t.CPtr, # ============================================================ # build_gep_array — 数组双索引 GEP: getelementptr [N x ty], [N x ty]* %ptr, i32 0, i32 %idx # ============================================================ -def build_gep_array(builder: IRBuilder | t.CPtr, array_ty: LLVMType | t.CPtr, - elem_ty: LLVMType | t.CPtr, - ptr: Value | t.CPtr, idx: Value | t.CPtr) -> Value | t.CPtr: +def build_gep_array(builder: rowptr[IRBuilder], array_ty: rowptr[LLVMType], + elem_ty: rowptr[LLVMType], + ptr: rowptr[Value], idx: rowptr[Value]) -> rowptr[Value]: """%N = getelementptr [N x elem_ty], [N x elem_ty]* %ptr, i32 0, i32 %idx 结果类型是 elem_ty* @@ -1630,9 +1630,9 @@ def build_gep_array(builder: IRBuilder | t.CPtr, array_ty: LLVMType | t.CPtr, # ============================================================ # build_gep_struct — 结构体字段 GEP: getelementptr struct_ty, struct_ty* %ptr, i32 0, i32 %field_idx # ============================================================ -def build_gep_struct(builder: IRBuilder | t.CPtr, struct_ty: LLVMType | t.CPtr, - field_ty: LLVMType | t.CPtr, - ptr: Value | t.CPtr, field_idx: t.CInt) -> Value | t.CPtr: +def build_gep_struct(builder: rowptr[IRBuilder], struct_ty: rowptr[LLVMType], + field_ty: rowptr[LLVMType], + ptr: rowptr[Value], field_idx: int) -> rowptr[Value]: """%N = getelementptr struct_ty, struct_ty* %ptr, i32 0, i32 %field_idx 结果类型是 field_ty* @@ -1648,16 +1648,16 @@ def build_gep_struct(builder: IRBuilder | t.CPtr, struct_ty: LLVMType | t.CPtr, # ============================================================ @t.NoVTable class PhiIncoming(GSListNode[PhiIncoming]): - Val: Value | t.CPtr - Block: BasicBlock | t.CPtr + Val: rowptr[Value] + Block: rowptr[BasicBlock] # PhiIncoming 硬编码大小: Next(8) + Val(8) + Block(8) = 24 字节 PHIINC_SIZE: t.CDefine = 24 -def new_phi_incoming(pool: memhub.MemBuddy | t.CPtr, - val: Value | t.CPtr, block: BasicBlock | t.CPtr) -> PhiIncoming | t.CPtr: - ptr: PhiIncoming | t.CPtr = pool.alloc(PHIINC_SIZE) +def new_phi_incoming(pool: rowptr[memhub.MemBuddy], + val: rowptr[Value], block: rowptr[BasicBlock]) -> rowptr[PhiIncoming]: + ptr: rowptr[PhiIncoming] = pool.alloc(PHIINC_SIZE) if ptr is None: return None string.memset(ptr, 0, PHIINC_SIZE) ptr.Val = val @@ -1668,8 +1668,8 @@ def new_phi_incoming(pool: memhub.MemBuddy | t.CPtr, # ============================================================ # Phi 指令 # ============================================================ -def build_phi(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr, - incoming_head: PhiIncoming | t.CPtr, count: t.CInt) -> Value | t.CPtr: +def build_phi(builder: rowptr[IRBuilder], ty: rowptr[LLVMType], + incoming_head: rowptr[PhiIncoming], count: int) -> rowptr[Value]: """%N = phi [val1, %blk1], [val2, %blk2], ... incoming_head 是 PhiIncoming 链表头,count 是入边数量。 @@ -1684,16 +1684,16 @@ def build_phi(builder: IRBuilder | t.CPtr, ty: LLVMType | t.CPtr, # ============================================================ @t.NoVTable class SwitchCase(GSListNode[SwitchCase]): - CaseVal: Value | t.CPtr - Block: BasicBlock | t.CPtr + CaseVal: rowptr[Value] + Block: rowptr[BasicBlock] # SwitchCase 硬编码大小: Next(8) + CaseVal(8) + Block(8) = 24 字节 SWCASE_SIZE: t.CDefine = 24 -def new_switch_case(pool: memhub.MemBuddy | t.CPtr, - case_val: Value | t.CPtr, block: BasicBlock | t.CPtr) -> SwitchCase | t.CPtr: - ptr: SwitchCase | t.CPtr = pool.alloc(SWCASE_SIZE) +def new_switch_case(pool: rowptr[memhub.MemBuddy], + case_val: rowptr[Value], block: rowptr[BasicBlock]) -> rowptr[SwitchCase]: + ptr: rowptr[SwitchCase] = pool.alloc(SWCASE_SIZE) if ptr is None: return None string.memset(ptr, 0, SWCASE_SIZE) ptr.CaseVal = case_val @@ -1704,9 +1704,9 @@ def new_switch_case(pool: memhub.MemBuddy | t.CPtr, # ============================================================ # Switch 指令 # ============================================================ -def build_switch(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, - default_blk: BasicBlock | t.CPtr, - cases_head: SwitchCase | t.CPtr, case_count: t.CInt): +def build_switch(builder: rowptr[IRBuilder], val: rowptr[Value], + default_blk: rowptr[BasicBlock], + cases_head: rowptr[SwitchCase], case_count: int): """switch , label % [, label % ...]""" builder.build_switch(val, default_blk, cases_head, case_count) @@ -1714,8 +1714,8 @@ def build_switch(builder: IRBuilder | t.CPtr, val: Value | t.CPtr, # ============================================================ # Select 指令 # ============================================================ -def build_select(builder: IRBuilder | t.CPtr, cond: Value | t.CPtr, - true_val: Value | t.CPtr, false_val: Value | t.CPtr) -> Value | t.CPtr: +def build_select(builder: rowptr[IRBuilder], cond: rowptr[Value], + true_val: rowptr[Value], false_val: rowptr[Value]) -> rowptr[Value]: """%N = select i1 , , """ return builder.build_select(cond, true_val, false_val) @@ -1723,7 +1723,7 @@ def build_select(builder: IRBuilder | t.CPtr, cond: Value | t.CPtr, # ============================================================ # Unreachable 指令 # ============================================================ -def build_unreachable(builder: IRBuilder | t.CPtr): +def build_unreachable(builder: rowptr[IRBuilder]): """unreachable""" builder.build_unreachable() @@ -1754,7 +1754,7 @@ ATOMIC_ORDER_ACQ_REL: t.CDefine = 5 ATOMIC_ORDER_SEQ_CST: t.CDefine = 6 -def _atomic_op_str(op: t.CInt) -> t.CChar | t.CPtr: +def _atomic_op_str(op: int) -> str: if op == ATOMIC_XCHG: return "xchg" if op == ATOMIC_ADD: return "add" if op == ATOMIC_SUB: return "sub" @@ -1769,7 +1769,7 @@ def _atomic_op_str(op: t.CInt) -> t.CChar | t.CPtr: return "xchg" -def _atomic_order_str(ord: t.CInt) -> t.CChar | t.CPtr: +def _atomic_order_str(ord: int) -> str: if ord == ATOMIC_ORDER_UNORDERED: return "unordered" if ord == ATOMIC_ORDER_MONOTONIC: return "monotonic" if ord == ATOMIC_ORDER_ACQUIRE: return "acquire" @@ -1779,16 +1779,16 @@ def _atomic_order_str(ord: t.CInt) -> t.CChar | t.CPtr: return "monotonic" -def build_atomicrmw(builder: IRBuilder | t.CPtr, op: t.CInt, - ptr: Value | t.CPtr, val: Value | t.CPtr, - order: t.CInt) -> Value | t.CPtr: +def build_atomicrmw(builder: rowptr[IRBuilder], op: int, + ptr: rowptr[Value], val: rowptr[Value], + order: int) -> rowptr[Value]: """%N = atomicrmw , """ return builder.build_atomicrmw(op, ptr, val, order) -def build_cmpxchg(builder: IRBuilder | t.CPtr, ptr: Value | t.CPtr, - cmp_val: Value | t.CPtr, new_val: Value | t.CPtr, - succ_order: t.CInt, fail_order: t.CInt) -> Value | t.CPtr: +def build_cmpxchg(builder: rowptr[IRBuilder], ptr: rowptr[Value], + cmp_val: rowptr[Value], new_val: rowptr[Value], + succ_order: int, fail_order: int) -> rowptr[Value]: """%N = cmpxchg , , 返回 {, i1} 类型的 SSA 值(简化为返回 i64 表示的值对) @@ -1799,9 +1799,9 @@ def build_cmpxchg(builder: IRBuilder | t.CPtr, ptr: Value | t.CPtr, # ============================================================ # va_arg 指令: 从 va_list 读取下一个变长参数 # ============================================================ -def build_va_arg(builder: IRBuilder | t.CPtr, - va_list_ptr: Value | t.CPtr, - arg_ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def build_va_arg(builder: rowptr[IRBuilder], + va_list_ptr: rowptr[Value], + arg_ty: rowptr[LLVMType]) -> rowptr[Value]: """%N = va_arg , """ return builder.build_va_arg(va_list_ptr, arg_ty) @@ -1809,9 +1809,9 @@ def build_va_arg(builder: IRBuilder | t.CPtr, # ============================================================ # 内联汇编 (Phase 3) # ============================================================ -def build_inline_asm(builder: IRBuilder | t.CPtr, ret_ty: LLVMType | t.CPtr, - asm_text: t.CChar | t.CPtr, constraints: t.CChar | t.CPtr, - has_side_effects: t.CInt) -> Value | t.CPtr: +def build_inline_asm(builder: rowptr[IRBuilder], ret_ty: rowptr[LLVMType], + asm_text: str, constraints: str, + has_side_effects: int) -> rowptr[Value]: """%N = call asm [sideeffect] "" ""() 简化的内联汇编调用,无参数版本。 @@ -1828,7 +1828,7 @@ def build_inline_asm(builder: IRBuilder | t.CPtr, ret_ty: LLVMType | t.CPtr, _g_last_dst: t.CUInt64T = 0 _g_last_pos: t.CSizeT = 0 -def _append_cstr(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPtr): +def _append_cstr(dst: str, dst_size: t.CSizeT, src: str): """将 C 字符串 src 追加到 dst 末尾""" global _g_last_dst, _g_last_pos if dst is None or src is None: return diff --git a/llvmlite/__function.vp b/llvmlite/__function.vp index 048356f..a657672 100644 --- a/llvmlite/__function.vp +++ b/llvmlite/__function.vp @@ -27,7 +27,7 @@ IR_DUMP_CHAIN_LIMIT: t.CDefine = 100000 # ============================================================ @t.NoVTable class Line(GSListNode[Line]): - Buf: t.CChar | t.CPtr # 行文本(NUL 结尾) + Buf: str # 行文本(NUL 结尾) Len: t.CSizeT # 文本长度(不含 NUL) @@ -42,9 +42,9 @@ class Line(GSListNode[Line]): # ============================================================ @t.NoVTable class BasicBlock(GSListNode[BasicBlock]): - Name: t.CChar | t.CPtr # 块名(如 "entry"/"if.then") - Lines: GSList[Line] | t.CPtr # 指令行链表容器(Head/Tail/Count) - IsTerminated: t.CInt # 1=已有终止指令(br/ret) + Name: str # 块名(如 "entry"/"if.then") + Lines: rowptr[GSList[Line]] # 指令行链表容器(Head/Tail/Count) + IsTerminated: int # 1=已有终止指令(br/ret) # ============================================================ @@ -57,9 +57,9 @@ class BasicBlock(GSListNode[BasicBlock]): # ============================================================ @t.NoVTable class Param(GSListNode[Param]): - Ty: LLVMType | t.CPtr # 参数类型 - Name: t.CChar | t.CPtr # 参数名(如 "%0"/"%a") - Attrs: t.CChar | t.CPtr # 参数属性文本(None=无属性) + Ty: rowptr[LLVMType] # 参数类型 + Name: str # 参数名(如 "%0"/"%a") + Attrs: str # 参数属性文本(None=无属性) # ============================================================ @@ -74,13 +74,15 @@ class Param(GSListNode[Param]): # ============================================================ @t.NoVTable class Function(GSListNode[Function]): - Name: t.CChar | t.CPtr # 函数名 - RetTy: LLVMType | t.CPtr # 返回类型 - Params: GSList[Param] | t.CPtr # 参数链表容器 - Blocks: GSList[BasicBlock] | t.CPtr # 基本块链表容器 - IsDeclared: t.CInt # 1=仅声明(declare), 0=定义(define) - IsVarArg: t.CInt # 1=变参函数(...) - Attrs: t.CChar | t.CPtr # 函数属性文本(None=无属性) + Name: str # 函数名 + RetTy: rowptr[LLVMType] # 返回类型 + Params: rowptr[GSList[Param]] # 参数链表容器 + Blocks: rowptr[GSList[BasicBlock]] # 基本块链表容器 + IsDeclared: int # 1=仅声明(declare), 0=定义(define) + IsVarArg: int # 1=变参函数(...) + Attrs: str # 函数属性文本(None=无属性) + AttrGroup: str # 字符串属性组内容(如 '"section"=".text.startup"',None=无) + AttrGroupId: int # 属性组编号(>0 时函数行输出 #N,模块尾输出 attributes #N) # ============================================================ @@ -89,14 +91,14 @@ class Function(GSListNode[Function]): # Line 硬编码大小: Next(8) + Buf(8) + Len(8) = 24 字节 LINE_SIZE: t.CDefine = 24 -def new_line(pool: memhub.MemBuddy | t.CPtr, text: t.CChar | t.CPtr) -> Line | t.CPtr: +def new_line(pool: rowptr[memhub.MemBuddy], text: str) -> rowptr[Line]: """创建一个指令行,复制 text 到新分配的缓冲区""" - ptr: Line | t.CPtr = pool.alloc(LINE_SIZE) + ptr: rowptr[Line] = pool.alloc(LINE_SIZE) if ptr is None: return None string.memset(ptr, 0, LINE_SIZE) if text is not None: slen: t.CSizeT = string.strlen(text) - buf: t.CChar | t.CPtr = pool.alloc(slen + 1) + buf: str = pool.alloc(slen + 1) if buf is not None: string.strcpy(buf, text) ptr.Buf = buf @@ -104,7 +106,7 @@ def new_line(pool: memhub.MemBuddy | t.CPtr, text: t.CChar | t.CPtr) -> Line | t return ptr -def _new_gslist(pool: memhub.MemBuddy | t.CPtr, list_size: t.CSizeT) -> t.CPtr: +def _new_gslist(pool: rowptr[memhub.MemBuddy], list_size: t.CSizeT) -> t.CPtr: """从 pool 分配并零初始化一个 GSList 容器(Head/Tail/Count 全零)""" gsl: t.CPtr = pool.alloc(list_size) if gsl is None: return None @@ -115,9 +117,9 @@ def _new_gslist(pool: memhub.MemBuddy | t.CPtr, list_size: t.CSizeT) -> t.CPtr: # BasicBlock 硬编码大小: Next(8) + Name(8) + Lines(8) + IsTerminated(4) = 32 字节 BLOCK_SIZE: t.CDefine = 32 -def new_basic_block(pool: memhub.MemBuddy | t.CPtr, name: t.CChar | t.CPtr) -> BasicBlock | t.CPtr: +def new_basic_block(pool: rowptr[memhub.MemBuddy], name: str) -> rowptr[BasicBlock]: """创建一个基本块""" - ptr: BasicBlock | t.CPtr = pool.alloc(BLOCK_SIZE) + ptr: rowptr[BasicBlock] = pool.alloc(BLOCK_SIZE) if ptr is None: return None string.memset(ptr, 0, BLOCK_SIZE) ptr.Name = name @@ -129,10 +131,10 @@ def new_basic_block(pool: memhub.MemBuddy | t.CPtr, name: t.CChar | t.CPtr) -> B # Param 硬编码大小: Next(8) + Ty(8) + Name(8) + Attrs(8) = 32 字节 PARAM_SIZE: t.CDefine = 32 -def new_param(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, - name: t.CChar | t.CPtr) -> Param | t.CPtr: +def new_param(pool: rowptr[memhub.MemBuddy], ty: rowptr[LLVMType], + name: str) -> rowptr[Param]: """创建一个函数参数""" - ptr: Param | t.CPtr = pool.alloc(PARAM_SIZE) + ptr: rowptr[Param] = pool.alloc(PARAM_SIZE) if ptr is None: return None string.memset(ptr, 0, PARAM_SIZE) ptr.Ty = ty @@ -141,13 +143,13 @@ def new_param(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, return ptr -# Function 硬编码大小: Next(8) + Name(8) + RetTy(8) + Params(8) + Blocks(8) + IsDeclared(4) + IsVarArg(4) + Attrs(8) = 56 字节 -FUNC_SIZE: t.CDefine = 56 +# Function 硬编码大小: Next(8) + Name(8) + RetTy(8) + Params(8) + Blocks(8) + IsDeclared(4) + IsVarArg(4) + Attrs(8) + AttrGroup(8) + AttrGroupId(8) = 72 字节 +FUNC_SIZE: t.CDefine = 72 -def new_function(pool: memhub.MemBuddy | t.CPtr, name: t.CChar | t.CPtr, - ret_ty: LLVMType | t.CPtr) -> Function | t.CPtr: +def new_function(pool: rowptr[memhub.MemBuddy], name: str, + ret_ty: rowptr[LLVMType]) -> rowptr[Function]: """创建一个函数""" - ptr: Function | t.CPtr = pool.alloc(FUNC_SIZE) + ptr: rowptr[Function] = pool.alloc(FUNC_SIZE) if ptr is None: return None string.memset(ptr, 0, FUNC_SIZE) ptr.Name = name @@ -156,32 +158,34 @@ def new_function(pool: memhub.MemBuddy | t.CPtr, name: t.CChar | t.CPtr, ptr.Blocks = _new_gslist(pool, 24) ptr.IsDeclared = 0 ptr.Attrs = None + ptr.AttrGroup = None + ptr.AttrGroupId = 0 return ptr # ============================================================ # 链表操作(委托 GSList.append) # ============================================================ -def function_add_param(func: Function | t.CPtr, param: Param | t.CPtr): +def function_add_param(func: rowptr[Function], param: rowptr[Param]): """将参数追加到函数参数链表""" if func is None or param is None: return # 注意:必须先用局部变量 + 类型参数(对齐 function_move_block_to_end 注释), # 链式 func.Params.append() 会被编译器解析成 LinkedNode.append 且 this 前移 # sizeof(LinkedNode)(兄弟 Mixin 兜底误匹配),写穿容器前 48 字节破坏数据结构。 - params: GSList[Param] | t.CPtr = func.Params + params: rowptr[GSList[Param]] = func.Params if params is None: return params.append(param) -def function_add_block(func: Function | t.CPtr, block: BasicBlock | t.CPtr): +def function_add_block(func: rowptr[Function], block: rowptr[BasicBlock]): """将基本块追加到函数块链表""" if func is None or block is None: return - blocks: GSList[BasicBlock] | t.CPtr = func.Blocks + blocks: rowptr[GSList[BasicBlock]] = func.Blocks if blocks is None: return blocks.append(block) -def function_move_block_to_end(func: Function | t.CPtr, block: BasicBlock | t.CPtr): +def function_move_block_to_end(func: rowptr[Function], block: rowptr[BasicBlock]): """将 block 移动到函数块链表末尾(保证 BB 文本顺序与控制流顺序一致)。 用于解决 SSA 名非单调问题:BB 按创建顺序排列,但指令按控制流顺序生成, @@ -192,7 +196,7 @@ def function_move_block_to_end(func: Function | t.CPtr, block: BasicBlock | t.CP struct 类型,导致 blocks.Head/Tail/Count 字段访问读取垃圾值。 """ if func is None or block is None: return - blocks: GSList[BasicBlock] | t.CPtr = func.Blocks + blocks: rowptr[GSList[BasicBlock]] = func.Blocks if blocks is None: return # 已经是 Tail,无需移动 @@ -205,7 +209,7 @@ def function_move_block_to_end(func: Function | t.CPtr, block: BasicBlock | t.CP blocks.Head = block.Next else: # 遍历找前驱 - prev: BasicBlock | t.CPtr = blocks.Head + prev: rowptr[BasicBlock] = blocks.Head while prev is not None and prev.Next is not block: prev = prev.Next if prev is None: @@ -223,39 +227,39 @@ def function_move_block_to_end(func: Function | t.CPtr, block: BasicBlock | t.CP blocks.Tail = block -def block_append_line(block: BasicBlock | t.CPtr, line: Line | t.CPtr): +def block_append_line(block: rowptr[BasicBlock], line: rowptr[Line]): """将指令行追加到基本块""" if block is None or line is None: return - lines: GSList[Line] | t.CPtr = block.Lines + lines: rowptr[GSList[Line]] = block.Lines if lines is None: return lines.append(line) -def block_set_terminated(block: BasicBlock | t.CPtr, val: t.CInt): +def block_set_terminated(block: rowptr[BasicBlock], val: int): """设置块的终止标志(供跨模块调用,避免链式属性访问的 opaque 类型问题)""" if block is None: return block.IsTerminated = val -def block_get_terminated(block: BasicBlock | t.CPtr) -> t.CInt: +def block_get_terminated(block: rowptr[BasicBlock]) -> int: """获取块的终止标志(供跨模块调用,避免链式属性访问的 opaque 类型问题)""" if block is None: return 1 return block.IsTerminated -def block_append_text(pool: memhub.MemBuddy | t.CPtr, block: BasicBlock | t.CPtr, - text: t.CChar | t.CPtr): +def block_append_text(pool: rowptr[memhub.MemBuddy], block: rowptr[BasicBlock], + text: str): """创建指令行并追加到基本块""" if block is None or text is None: return - line: Line | t.CPtr = new_line(pool, text) + line: rowptr[Line] = new_line(pool, text) if line is not None: block_append_line(block, line) -def block_insert_text_before_terminator(pool: memhub.MemBuddy | t.CPtr, - block: BasicBlock | t.CPtr, - text: t.CChar | t.CPtr): +def block_insert_text_before_terminator(pool: rowptr[memhub.MemBuddy], + block: rowptr[BasicBlock], + text: str): """创建指令行并插入到基本块终止指令之前 如果块未终止,追加到末尾。 @@ -264,14 +268,14 @@ def block_insert_text_before_terminator(pool: memhub.MemBuddy | t.CPtr, """ if block is None or text is None: return if block.Lines is None: return - line: Line | t.CPtr = new_line(pool, text) + line: rowptr[Line] = new_line(pool, text) if line is None: return # 块未终止:直接追加 if block.IsTerminated == 0: block_append_line(block, line) return # 块已终止:在 Tail(终止指令)之前插入 - lines: GSList[Line] | t.CPtr = block.Lines + lines: rowptr[GSList[Line]] = block.Lines if lines.Head is None: block_append_line(block, line) return @@ -282,7 +286,7 @@ def block_insert_text_before_terminator(pool: memhub.MemBuddy | t.CPtr, lines.Count += 1 return # 找到 Tail 的前驱节点 - prev: Line | t.CPtr = lines.Head + prev: rowptr[Line] = lines.Head while prev is not None and prev.Next is not lines.Tail: prev = prev.Next if prev is None: @@ -298,18 +302,29 @@ def block_insert_text_before_terminator(pool: memhub.MemBuddy | t.CPtr, # ============================================================ # 属性设置 # ============================================================ -def function_set_attrs(func: Function | t.CPtr, attrs: t.CChar | t.CPtr): +def function_set_attrs(func: rowptr[Function], attrs: str): """设置函数级属性文本(如 "nounwind"/"noinline")""" if func is None: return - # [ATTR-DIAG] 确认 function_set_attrs 是否被调用及传入内容 - if attrs is not None: - stdio.printf("[ATTR] function_set_attrs: func='%s' attrs='%s'\n", func.Name, attrs) - else: - stdio.printf("[ATTR] function_set_attrs: func='%s' attrs=None\n", func.Name) func.Attrs = attrs -def param_set_attrs(param: Param | t.CPtr, attrs: t.CChar | t.CPtr): +_g_attr_group_counter: int = 0 + +def function_set_attr_group(func: rowptr[Function], group: str): + """设置函数字符串属性组(如 '"section"=".text.startup"')并分配组编号 #N。 + + LLVM 字符串属性(带值的,如 section)不能内联在函数签名行, + 必须用属性组:函数行输出 #N,组定义输出在函数尾。 + """ + global _g_attr_group_counter + if func is None or group is None: + return + func.AttrGroup = group + _g_attr_group_counter += 1 + func.AttrGroupId = _g_attr_group_counter + + +def param_set_attrs(param: rowptr[Param], attrs: str): """设置参数属性文本(如 "noundef"/"nocapture"/"readonly")""" if param is None: return param.Attrs = attrs @@ -324,7 +339,7 @@ def param_set_attrs(param: Param | t.CPtr, attrs: t.CChar | t.CPtr): # SHA1 命名空间的函数名(如 "4dad2ba72ed7ba09.GSListNode[Param]")含 '['、']', # 需要加引号;但纯 hex+点 的名字(如 "abc.def")不需要。 # ============================================================ -def _ll_name_needs_quote(name: str) -> t.CInt: +def _ll_name_needs_quote(name: str) -> int: """检查 LLVM 标识符是否需要加引号(以数字开头或含非合法字符) LLVM IR 合法字符:a-z, A-Z, 0-9, -, $, ., _ @@ -373,7 +388,7 @@ def _ll_name_needs_quote(name: str) -> t.CInt: # ============================================================ # 判定字符是否为十进制数字 -def _is_digit_ch(ch: t.CChar) -> t.CInt: +def _is_digit_ch(ch: t.CChar) -> int: """判断字符是否是 '0'-'9' ch 是值类型 (t.CChar = i8),TPC 已修复值类型 is None 处理: @@ -393,56 +408,56 @@ def _is_digit_ch(ch: t.CChar) -> t.CInt: # 导致内存损坏。必须显式计算字节偏移:addr = base + idx * 4,再转型为 i32*。 # 参见 HandlesTranslator.py:358 的 t.CUInt64T(ptr) + offset * sizeof 用法。 # ============================================================ -def _map_get_i32(map_arr: t.CChar | t.CPtr, idx: t.CInt) -> t.CInt: +def _map_get_i32(map_arr: str, idx: int) -> int: """读取 i32 数组 map_arr[idx](显式字节偏移 idx*4) - 使用 (t.CInt | t.CPtr)(uint64) 强转将字节偏移转为 i32*,再用 c.Deref 解引用。 + 使用 (rowptr[int])(uint64) 强转将字节偏移转为 i32*,再用 c.Deref 解引用。 TPC 已修复类型联合强转(_HandleTypeUnionCastLlvm 添加 fallback),此写法可用。 """ if map_arr is None: return -1 byte_off: t.CUInt64T = t.CUInt64T(map_arr) + idx * 4 - elem_ptr: t.CInt | t.CPtr = (t.CInt | t.CPtr)(byte_off) + elem_ptr: rowptr[int] = (rowptr[int])(byte_off) return c.Deref(elem_ptr) -def _map_set_i32(map_arr: t.CChar | t.CPtr, idx: t.CInt, val: t.CInt): +def _map_set_i32(map_arr: str, idx: int, val: int): """写入 map_arr[idx] = val(i32 数组,显式字节偏移 idx*4) - 使用 (t.CInt | t.CPtr)(uint64) 强转 + c.DerefAs 解引用赋值。 + 使用 (rowptr[int])(uint64) 强转 + c.DerefAs 解引用赋值。 TPC 已修复类型联合强转,此写法可用。 """ if map_arr is None: return byte_off: t.CUInt64T = t.CUInt64T(map_arr) + idx * 4 - elem_ptr: t.CInt | t.CPtr = (t.CInt | t.CPtr)(byte_off) + elem_ptr: rowptr[int] = (rowptr[int])(byte_off) c.DerefAs(elem_ptr, val) -def _scan_max_ssa_in_text(text: t.CChar | t.CPtr, cur_max: t.CInt) -> t.CInt: +def _scan_max_ssa_in_text(text: str, cur_max: int) -> int: """扫描文本,找出 %N(N 为数字)中最大的 N,与 cur_max 比较返回更大值 仅匹配 '%' 后紧跟数字的情况,跳过命名 SSA 名(%entry 等)。 """ - result: t.CInt = cur_max - p: t.CChar | t.CPtr = text + result: int = cur_max + p: str = text while p is not None and p[0] != '\0': if p[0] == '%': - nxt: t.CChar | t.CPtr = p + 1 + nxt: str = p + 1 if nxt is not None and _is_digit_ch(nxt[0]) != 0: - num: t.CInt = string.atoi(nxt) + num: int = string.atoi(nxt) if num > result: result = num p = p + 1 return result -def _find_max_ssa_number(func: Function | t.CPtr) -> t.CInt: +def _find_max_ssa_number(func: rowptr[Function]) -> int: """遍历所有 BB 指令行,找出最大的 %N 数字;无数字 SSA 名返回 -1""" - max_n: t.CInt = -1 + max_n: int = -1 if func is None or func.Blocks is None: return max_n - blk: BasicBlock | t.CPtr = func.Blocks.Head + blk: rowptr[BasicBlock] = func.Blocks.Head blk_steps: t.CSizeT = 0 while blk is not None: blk_steps += 1 @@ -450,7 +465,7 @@ def _find_max_ssa_number(func: Function | t.CPtr) -> t.CInt: stdio.printf("[IR-DUMP] 链表成环: func blocks(函数名=%s,ssa 扫描终止)\n", func.Name) stdlib.exit(1) if blk.Lines is not None: - line: Line | t.CPtr = blk.Lines.Head + line: rowptr[Line] = blk.Lines.Head line_steps: t.CSizeT = 0 while line is not None: line_steps += 1 @@ -465,20 +480,20 @@ def _find_max_ssa_number(func: Function | t.CPtr) -> t.CInt: return max_n -def _assign_new_numbers(text: t.CChar | t.CPtr, - map_arr: t.CChar | t.CPtr, - max_n: t.CInt, next_new: t.CInt) -> t.CInt: +def _assign_new_numbers(text: str, + map_arr: str, + max_n: int, next_new: int) -> int: """扫描文本,对每个 %N(数字),若 map_arr[N]==-1 则分配 next_new 返回更新后的 next_new。按文本首次出现顺序建立映射。 """ - result: t.CInt = next_new - p: t.CChar | t.CPtr = text + result: int = next_new + p: str = text while p is not None and p[0] != '\0': if p[0] == '%': - nxt: t.CChar | t.CPtr = p + 1 + nxt: str = p + 1 if nxt is not None and _is_digit_ch(nxt[0]) != 0: - num: t.CInt = string.atoi(nxt) + num: int = string.atoi(nxt) if num >= 0 and num <= max_n: if _map_get_i32(map_arr, num) == -1: _map_set_i32(map_arr, num, result) @@ -487,10 +502,10 @@ def _assign_new_numbers(text: t.CChar | t.CPtr, return result -def _replace_ssa_numbers(text: t.CChar | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, - map_arr: t.CChar | t.CPtr, - max_n: t.CInt) -> t.CChar | t.CPtr: +def _replace_ssa_numbers(text: str, + pool: rowptr[memhub.MemBuddy], + map_arr: str, + max_n: int) -> str: """构建新文本,将 %N 替换为映射后的新编号 逐字符扫描:遇到 %N(数字)查映射表替换,其他字符原样复制。 @@ -499,29 +514,29 @@ def _replace_ssa_numbers(text: t.CChar | t.CPtr, src_len: t.CSizeT = string.strlen(text) # 新缓冲区:最坏情况每个数字变长(位数增加),分配 src_len*2 + 64 new_size: t.CSizeT = src_len * 2 + 64 - new_buf: t.CChar | t.CPtr = pool.alloc(new_size) + new_buf: str = pool.alloc(new_size) if new_buf is None: return None # 一次性分配数字缓冲区(循环中复用) - num_buf: t.CChar | t.CPtr = pool.alloc(16) + num_buf: str = pool.alloc(16) if num_buf is None: new_buf[0] = '\0' return new_buf dst_idx: t.CSizeT = 0 - src_p: t.CChar | t.CPtr = text + src_p: str = text while src_p is not None and src_p[0] != '\0': if dst_idx + 16 >= new_size: # 缓冲区不足,截断 break if src_p[0] == '%': - nxt: t.CChar | t.CPtr = src_p + 1 + nxt: str = src_p + 1 if nxt is not None and _is_digit_ch(nxt[0]) != 0: - num: t.CInt = string.atoi(nxt) + num: int = string.atoi(nxt) # 先做范围检查再读 map_arr:num 超 max_n 时 map_arr 只有 # (max_n+1)*4 字节,先读后查会越界读远端内存 if num >= 0 and num <= max_n: - new_num: t.CInt = _map_get_i32(map_arr, num) + new_num: int = _map_get_i32(map_arr, num) if new_num != -1: # 写入 '%' new_buf[dst_idx] = '%' @@ -548,7 +563,7 @@ def _replace_ssa_numbers(text: t.CChar | t.CPtr, return new_buf -def RenumberSSA(func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): +def RenumberSSA(func: rowptr[Function], pool: rowptr[memhub.MemBuddy]): """重编号函数内所有数字 SSA 名,确保按文本输出顺序单调递增 在 FunctionPrint 序列化函数体之前调用。 @@ -562,7 +577,7 @@ def RenumberSSA(func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): return # 1. 第一遍扫描:找出最大 SSA 编号 - max_n: t.CInt = _find_max_ssa_number(func) + max_n: int = _find_max_ssa_number(func) if max_n < 0: return # 无数字 SSA 名 @@ -570,15 +585,15 @@ def RenumberSSA(func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): # 用 i8* 存储(pool.alloc 返回 i8*),通过 _map_get_i32/_map_set_i32 访问。 # 初始化为 -1:每个 i32 元素 4 字节,0xFFFFFFFF = -1(有符号 i32)。 # 用 memset 一次性填充,避免循环内 ptr[i] 指针索引问题。 - map_bytes: t.CSizeT = (max_n + 1) * 4 # t.CInt = 4 字节 - map_arr: t.CChar | t.CPtr = pool.alloc(map_bytes) + map_bytes: t.CSizeT = (max_n + 1) * 4 # int = 4 字节 + map_arr: str = pool.alloc(map_bytes) if map_arr is None: return string.memset(map_arr, 0xFF, map_bytes) # 0xFF * 4 = 0xFFFFFFFF = -1 # 3. 第二遍扫描:按文本顺序分配新编号 - next_new: t.CInt = 0 - blk: BasicBlock | t.CPtr = func.Blocks.Head + next_new: int = 0 + blk: rowptr[BasicBlock] = func.Blocks.Head blk_steps: t.CSizeT = 0 while blk is not None: blk_steps += 1 @@ -586,7 +601,7 @@ def RenumberSSA(func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): stdio.printf("[IR-DUMP] 链表成环: func blocks(函数名=%s,ssa 重编号终止)\n", func.Name) stdlib.exit(1) if blk.Lines is not None: - line: Line | t.CPtr = blk.Lines.Head + line: rowptr[Line] = blk.Lines.Head line_steps: t.CSizeT = 0 while line is not None: line_steps += 1 @@ -600,10 +615,10 @@ def RenumberSSA(func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): blk = blk.Next # 4. 检查是否有需要重编号的(old != new) - need_renumber: t.CInt = 0 - i: t.CInt = 0 + need_renumber: int = 0 + i: int = 0 while i <= max_n: - v: t.CInt = _map_get_i32(map_arr, i) + v: int = _map_get_i32(map_arr, i) if v != -1 and v != i: need_renumber = 1 break @@ -620,7 +635,7 @@ def RenumberSSA(func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): stdio.printf("[IR-DUMP] 链表成环: func blocks(函数名=%s,ssa 替换终止)\n", func.Name) stdlib.exit(1) if blk.Lines is not None: - line: Line | t.CPtr = blk.Lines.Head + line: rowptr[Line] = blk.Lines.Head line_steps = 0 while line is not None: line_steps += 1 @@ -629,7 +644,7 @@ def RenumberSSA(func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): func.Name, blk.Name) stdlib.exit(1) if line.Buf is not None: - new_buf: t.CChar | t.CPtr = _replace_ssa_numbers( + new_buf: str = _replace_ssa_numbers( line.Buf, pool, map_arr, max_n) if new_buf is not None: line.Buf = new_buf @@ -650,8 +665,8 @@ def RenumberSSA(func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): # # } # ============================================================ -def FunctionPrint(buf: t.CChar | t.CPtr, size: t.CSizeT, - func: Function | t.CPtr, pool: memhub.MemBuddy | t.CPtr): +def FunctionPrint(buf: str, size: t.CSizeT, + func: rowptr[Function], pool: rowptr[memhub.MemBuddy]): """将函数 func 序列化为 IR 文本写入 buf""" if func is None or buf is None or size == 0: return @@ -661,7 +676,7 @@ def FunctionPrint(buf: t.CChar | t.CPtr, size: t.CSizeT, # RenumberSSA 内部会跳过 declare 函数(IsDeclared==1),无需在此判断。 RenumberSSA(func, pool) - ty_buf: t.CChar | t.CPtr = pool.alloc(128) + ty_buf: str = pool.alloc(128) if ty_buf is None: return ty_buf[0] = '\0' @@ -690,10 +705,10 @@ def FunctionPrint(buf: t.CChar | t.CPtr, size: t.CSizeT, _append_cstr(buf, size, "(") # 参数列表(从 GSList[Param].Head 遍历) - cur: Param | t.CPtr = None + cur: rowptr[Param] = None if func.Params is not None: cur = func.Params.Head - first: t.CInt = 1 + first: int = 1 cur_steps: t.CSizeT = 0 while cur is not None: cur_steps += 1 @@ -735,15 +750,23 @@ def FunctionPrint(buf: t.CChar | t.CPtr, size: t.CSizeT, if func.Attrs is not None: _append_cstr(buf, size, " ") _append_cstr(buf, size, func.Attrs) + # B5:字符串属性(section 等)必须用属性组 #N 引用(LLVM 不接受内联 + # section="..."),函数行输出 #N,组定义在函数尾/模块中输出。 + if func.AttrGroup is not None and func.AttrGroupId > 0: + ag_ref: str = pool.alloc(32) + if ag_ref is not None: + viperlib.snprintf(ag_ref, 32, " #%d", func.AttrGroupId) + _append_cstr(buf, size, ag_ref) if func.IsDeclared == 1: _append_cstr(buf, size, "\n") + _append_attr_group_def(buf, size, pool, func) return # 函数体 _append_cstr(buf, size, " {\n") - blk: BasicBlock | t.CPtr = None + blk: rowptr[BasicBlock] = None if func.Blocks is not None: blk = func.Blocks.Head blk_steps: t.CSizeT = 0 @@ -757,10 +780,10 @@ def FunctionPrint(buf: t.CChar | t.CPtr, size: t.CSizeT, _append_cstr(buf, size, blk.Name) _append_cstr(buf, size, ":\n") # 指令行(从 GSList[Line].Head 遍历) - line: Line | t.CPtr = None + line: rowptr[Line] = None if blk.Lines is not None: line = blk.Lines.Head - has_lines: t.CInt = 0 + has_lines: int = 0 line_steps: t.CSizeT = 0 while line is not None: line_steps += 1 @@ -785,6 +808,21 @@ def FunctionPrint(buf: t.CChar | t.CPtr, size: t.CSizeT, blk = blk.Next _append_cstr(buf, size, "}\n") + _append_attr_group_def(buf, size, pool, func) + + +def _append_attr_group_def(buf: str, size: t.CSizeT, + pool: rowptr[memhub.MemBuddy], + func: rowptr[Function]): + """输出字符串属性组定义: attributes #N = { "section"="..." }""" + if func is None or func.AttrGroup is None or func.AttrGroupId <= 0: + return + ag_buf: str = pool.alloc(192) + if ag_buf is None: + return + viperlib.snprintf(ag_buf, 192, "attributes #%d = { %s }\n", + func.AttrGroupId, func.AttrGroup) + _append_cstr(buf, size, ag_buf) # ============================================================ @@ -796,7 +834,7 @@ def FunctionPrint(buf: t.CChar | t.CPtr, size: t.CSizeT, _g_last_dst: t.CUInt64T = 0 _g_last_pos: t.CSizeT = 0 -def _append_cstr(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPtr): +def _append_cstr(dst: str, dst_size: t.CSizeT, src: str): """将 C 字符串 src 追加到 dst 末尾""" global _g_last_dst, _g_last_pos if dst is None or src is None: return @@ -834,28 +872,28 @@ def _append_cstr(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPt # 这些访问器在拥有完整类型定义的本模块内执行,能正确访问 # 所有字段。其他模块通过函数调用获取字段值,绕过 stub 限制。 # ============================================================ -def function_get_name(func: Function | t.CPtr) -> t.CChar | t.CPtr: +def function_get_name(func: rowptr[Function]) -> str: """获取函数名""" if func is None: return None return func.Name -def function_get_ret_ty(func: Function | t.CPtr) -> LLVMType | t.CPtr: +def function_get_ret_ty(func: rowptr[Function]) -> rowptr[LLVMType]: """获取函数返回类型""" if func is None: return None return func.RetTy -def function_get_params(func: Function | t.CPtr) -> GSList[Param] | t.CPtr: +def function_get_params(func: rowptr[Function]) -> rowptr[GSList[Param]]: """获取函数参数链表容器""" if func is None: return None return func.Params -def function_get_param_head(func: Function | t.CPtr) -> Param | t.CPtr: +def function_get_param_head(func: rowptr[Function]) -> rowptr[Param]: """获取函数参数链表头节点(一步到位,避免调用方访问 GSList.Head)""" if func is None: return None @@ -864,35 +902,35 @@ def function_get_param_head(func: Function | t.CPtr) -> Param | t.CPtr: return func.Params.Head -def function_get_next(func: Function | t.CPtr) -> Function | t.CPtr: +def function_get_next(func: rowptr[Function]) -> rowptr[Function]: """获取链表下一个函数""" if func is None: return None return func.Next -def function_is_declared(func: Function | t.CPtr) -> t.CInt: +def function_is_declared(func: rowptr[Function]) -> int: """获取函数是否为声明(1=declare 仅声明, 0=define 定义)""" if func is None: return 0 return func.IsDeclared -def param_get_name(param: Param | t.CPtr) -> t.CChar | t.CPtr: +def param_get_name(param: rowptr[Param]) -> str: """获取参数名""" if param is None: return None return param.Name -def param_get_ty(param: Param | t.CPtr) -> LLVMType | t.CPtr: +def param_get_ty(param: rowptr[Param]) -> rowptr[LLVMType]: """获取参数类型""" if param is None: return None return param.Ty -def param_get_next(param: Param | t.CPtr) -> Param | t.CPtr: +def param_get_next(param: rowptr[Param]) -> rowptr[Param]: """获取链表下一个参数""" if param is None: return None diff --git a/llvmlite/__init__.vp b/llvmlite/__init__.vp index c5eb10d..26d433a 100644 --- a/llvmlite/__init__.vp +++ b/llvmlite/__init__.vp @@ -25,6 +25,7 @@ from .__function import ( function_add_param, function_add_block, block_append_line, block_append_text, function_set_attrs, param_set_attrs, + function_set_attr_group, function_get_name, function_get_ret_ty, function_get_params, function_get_param_head, function_get_next, function_is_declared, param_get_name, param_get_ty, param_get_next, @@ -33,6 +34,7 @@ from .__function import ( from .__module import ( LLVMModule, GlobalVariable, NamedTypeNode, new_module, new_global_variable, module_add_function, module_add_global, module_add_named_type, + module_set_named_type_packed, module_set_target, module_set_datalayout, global_set_constant, global_set_linkage, global_set_unnamed_addr, global_set_section, LLVMModulePrint, OUTPUT_FULL, OUTPUT_STUB, OUTPUT_TEXT, @@ -77,11 +79,11 @@ from .__verify import ( # ============================================================ # 便捷工厂: 字符串复制 # ============================================================ -def _str_dup(pool: memhub.MemBuddy | t.CPtr, src: t.CChar | t.CPtr) -> t.CChar | t.CPtr: +def _str_dup(pool: rowptr[memhub.MemBuddy], src: str) -> str: """从 pool 分配并复制一个 C 字符串""" if src is None: return None slen: t.CSizeT = string.strlen(src) - buf: t.CChar | t.CPtr = pool.alloc(slen + 1) + buf: str = pool.alloc(slen + 1) if buf is None: return None string.strcpy(buf, src) return buf @@ -90,14 +92,14 @@ def _str_dup(pool: memhub.MemBuddy | t.CPtr, src: t.CChar | t.CPtr) -> t.CChar | # ============================================================ # 便捷工厂: 创建带名称的基本块 # ============================================================ -def create_block(pool: memhub.MemBuddy | t.CPtr, func: Function | t.CPtr, - name: t.CChar | t.CPtr) -> BasicBlock | t.CPtr: +def create_block(pool: rowptr[memhub.MemBuddy], func: rowptr[Function], + name: str) -> rowptr[BasicBlock]: """创建基本块并添加到函数""" # 块名与函数参数值名冲突防护:LLVM 中块标签 "entry:" 即值 %entry, # 与参数 %entry 重名 → llc "unable to create block named 'entry'" # (CallGenCall._field_byte_offset(self, pool, entry, ...) 根因)。 # 冲突时追加 .1/.2/... 后缀去重(Param.Name 可能带 % 前缀,剥离比较)。 - use_name: t.CChar | t.CPtr = name + use_name: str = name if func is not None and func.Params is not None and name is not None \ and name[0] != '\0': cb_len: t.CSizeT = string.strlen(name) + 16 @@ -107,7 +109,7 @@ def create_block(pool: memhub.MemBuddy | t.CPtr, func: Function | t.CPtr, cb_collide: int = 1 while cb_collide != 0: cb_collide = 0 - cb_p: Param | t.CPtr = function_get_param_head(func) + cb_p: rowptr[Param] = function_get_param_head(func) while cb_p is not None: cb_pnm: str = param_get_name(cb_p) if cb_pnm is not None: @@ -122,8 +124,8 @@ def create_block(pool: memhub.MemBuddy | t.CPtr, func: Function | t.CPtr, viperlib.snprintf(cb_buf, cb_len, "%s.%d", name, cb_k) use_name = cb_buf cb_k += 1 - name_dup: t.CChar | t.CPtr = _str_dup(pool, use_name) - blk: BasicBlock | t.CPtr = new_basic_block(pool, name_dup) + name_dup: str = _str_dup(pool, use_name) + blk: rowptr[BasicBlock] = new_basic_block(pool, name_dup) if blk is not None: function_add_block(func, blk) return blk @@ -132,8 +134,8 @@ def create_block(pool: memhub.MemBuddy | t.CPtr, func: Function | t.CPtr, # ============================================================ # 便捷工厂: 创建整数常量值 # ============================================================ -def const_int(pool: memhub.MemBuddy | t.CPtr, bits: t.CInt, - val: t.CInt64T) -> Value | t.CPtr: +def const_int(pool: rowptr[memhub.MemBuddy], bits: int, + val: int64) -> rowptr[Value]: """创建整数常量值(自动创建类型 + 名字文本) 参数: @@ -141,13 +143,13 @@ def const_int(pool: memhub.MemBuddy | t.CPtr, bits: t.CInt, val: 整数值 """ # 创建类型 - ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if ty is None: return None string.memset(ty, 0, LLVMType.__sizeof__()) c.DerefAs(ty, LLVMType.Int(bits)) # 创建名字文本 - name: t.CChar | t.CPtr = pool.alloc(32) + name: str = pool.alloc(32) if name is None: return None # LLVM i64 字面量范围不含 INT64_MIN(-9223372036854775808):该值必须 # 用无符号位模式 9223372036854775808 表示(LLVM 接受),否则 opt 解析 @@ -161,12 +163,12 @@ def const_int(pool: memhub.MemBuddy | t.CPtr, bits: t.CInt, return ConstInt(pool, ty, val, name) -def const_int32(pool: memhub.MemBuddy | t.CPtr, val: t.CInt64T) -> Value | t.CPtr: +def const_int32(pool: rowptr[memhub.MemBuddy], val: int64) -> rowptr[Value]: """便捷: 创建 i32 整数常量""" return const_int(pool, 32, val) -def const_int64(pool: memhub.MemBuddy | t.CPtr, val: t.CInt64T) -> Value | t.CPtr: +def const_int64(pool: rowptr[memhub.MemBuddy], val: int64) -> rowptr[Value]: """便捷: 创建 i64 整数常量""" return const_int(pool, 64, val) @@ -174,21 +176,21 @@ def const_int64(pool: memhub.MemBuddy | t.CPtr, val: t.CInt64T) -> Value | t.CPt # ============================================================ # 便捷工厂: 创建函数并添加到模块 # ============================================================ -def create_function(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPtr, - name: t.CChar | t.CPtr, ret_ty: LLVMType | t.CPtr) -> Function | t.CPtr: +def create_function(pool: rowptr[memhub.MemBuddy], mod: rowptr[LLVMModule], + name: str, ret_ty: rowptr[LLVMType]) -> rowptr[Function]: """创建函数并添加到模块""" - name_dup: t.CChar | t.CPtr = _str_dup(pool, name) - func: Function | t.CPtr = new_function(pool, name_dup, ret_ty) + name_dup: str = _str_dup(pool, name) + func: rowptr[Function] = new_function(pool, name_dup, ret_ty) if func is not None: module_add_function(mod, func) return func -def add_param(pool: memhub.MemBuddy | t.CPtr, func: Function | t.CPtr, - ty: LLVMType | t.CPtr, name: t.CChar | t.CPtr) -> Param | t.CPtr: +def add_param(pool: rowptr[memhub.MemBuddy], func: rowptr[Function], + ty: rowptr[LLVMType], name: str) -> rowptr[Param]: """创建参数并添加到函数""" - name_dup: t.CChar | t.CPtr = _str_dup(pool, name) - param: Param | t.CPtr = new_param(pool, ty, name_dup) + name_dup: str = _str_dup(pool, name) + param: rowptr[Param] = new_param(pool, ty, name_dup) if param is not None: function_add_param(func, param) return param @@ -197,15 +199,15 @@ def add_param(pool: memhub.MemBuddy | t.CPtr, func: Function | t.CPtr, # ============================================================ # 便捷工厂: 创建函数声明(declare) # ============================================================ -def create_declare(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPtr, - name: t.CChar | t.CPtr, ret_ty: LLVMType | t.CPtr) -> Function | t.CPtr: +def create_declare(pool: rowptr[memhub.MemBuddy], mod: rowptr[LLVMModule], + name: str, ret_ty: rowptr[LLVMType]) -> rowptr[Function]: """创建函数声明(declare,无函数体)并添加到模块 与 create_function 不同,声明不生成函数体,仅生成: declare @() """ - name_dup: t.CChar | t.CPtr = _str_dup(pool, name) - func: Function | t.CPtr = new_function(pool, name_dup, ret_ty) + name_dup: str = _str_dup(pool, name) + func: rowptr[Function] = new_function(pool, name_dup, ret_ty) if func is not None: func.IsDeclared = 1 module_add_function(mod, func) @@ -218,8 +220,8 @@ def create_declare(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPtr, # 生成 LLVM IR: # @.str = private unnamed_addr constant [N x i8] c"contents\00" # ============================================================ -def create_global_string(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPtr, - name: t.CChar | t.CPtr, text: t.CChar | t.CPtr) -> GlobalVariable | t.CPtr: +def create_global_string(pool: rowptr[memhub.MemBuddy], mod: rowptr[LLVMModule], + name: str, text: str) -> rowptr[GlobalVariable]: """创建字符串常量全局变量并添加到模块 参数: @@ -230,23 +232,23 @@ def create_global_string(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPt """ if text is None: return None slen: t.CSizeT = string.strlen(text) - count: t.CInt = slen + 1 # 含末尾 NUL + count: int = slen + 1 # 含末尾 NUL # 创建 i8 类型 - i8_ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + i8_ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if i8_ty is None: return None string.memset(i8_ty, 0, LLVMType.__sizeof__()) c.DerefAs(i8_ty, LLVMType.Int(8)) # 创建 [count x i8] 数组类型 - arr_ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + arr_ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if arr_ty is None: return None string.memset(arr_ty, 0, LLVMType.__sizeof__()) c.DerefAs(arr_ty, LLVMType.Array(i8_ty, count)) # 创建全局变量 - name_dup: t.CChar | t.CPtr = _str_dup(pool, name) - gv: GlobalVariable | t.CPtr = new_global_variable(pool, name_dup, arr_ty) + name_dup: str = _str_dup(pool, name) + gv: rowptr[GlobalVariable] = new_global_variable(pool, name_dup, arr_ty) if gv is None: return None # 设置属性: private + unnamed_addr + constant @@ -257,7 +259,7 @@ def create_global_string(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPt # 构造初始化值文本: c"contents\00" # LLVM IR 字符串字面量格式: c"" 其中 " 和 \ 及非打印字符用 \xx 转义 # 缓冲区大小: 最坏情况每个字符4字节(\xx)+ c"..." + \00 + " - init_buf: t.CChar | t.CPtr = pool.alloc(slen * 4 + 8) + init_buf: str = pool.alloc(slen * 4 + 8) if init_buf is None: return None pos: t.CSizeT = 0 init_buf[pos] = 'c' @@ -271,8 +273,8 @@ def create_global_string(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPt # 需要转义: " → \22, \ → \5c, 非打印字符 → \xx init_buf[pos] = '\\' pos += 1 - hi: t.CInt = (ch >> 4) & 0x0F - lo: t.CInt = ch & 0x0F + hi: int = (ch >> 4) & 0x0F + lo: int = ch & 0x0F if hi < 10: init_buf[pos] = 0x30 + hi else: @@ -306,25 +308,25 @@ def create_global_string(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPt # ============================================================ # 便捷工厂: 创建带初始化值的整数全局变量 # ============================================================ -def create_global_int(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPtr, - name: t.CChar | t.CPtr, bits: t.CInt, val: t.CInt64T) -> GlobalVariable | t.CPtr: +def create_global_int(pool: rowptr[memhub.MemBuddy], mod: rowptr[LLVMModule], + name: str, bits: int, val: int64) -> rowptr[GlobalVariable]: """创建整数全局变量并添加到模块 生成 LLVM IR: @ = global i """ # 创建整数类型 - ty: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + ty: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if ty is None: return None string.memset(ty, 0, LLVMType.__sizeof__()) c.DerefAs(ty, LLVMType.Int(bits)) - name_dup: t.CChar | t.CPtr = _str_dup(pool, name) - gv: GlobalVariable | t.CPtr = new_global_variable(pool, name_dup, ty) + name_dup: str = _str_dup(pool, name) + gv: rowptr[GlobalVariable] = new_global_variable(pool, name_dup, ty) if gv is None: return None # 构造初始化值文本: "42" (类型由 _print_global 单独打印) - init_buf: t.CChar | t.CPtr = pool.alloc(48) + init_buf: str = pool.alloc(48) if init_buf is None: return None viperlib.snprintf(init_buf, 48, "%lld", val) gv.Initializer = init_buf @@ -337,123 +339,123 @@ def create_global_int(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPtr, # LLVMModuleCore: 模块/函数/值创建核心,封装 pool 避免重复传参 # # 用法: -# mcore: LLVMModuleCore | t.CPtr = LLVMModuleCore(pool) -# mod: LLVMModule | t.CPtr = mcore.NewModule("test") -# func: Function | t.CPtr = mcore.CreateFunction(mod, "add", ty_i32) -# val: Value | t.CPtr = mcore.ConstInt32(42) +# mcore: rowptr[LLVMModuleCore] = LLVMModuleCore(pool) +# mod: rowptr[LLVMModule] = mcore.NewModule("test") +# func: rowptr[Function] = mcore.CreateFunction(mod, "add", ty_i32) +# val: rowptr[Value] = mcore.ConstInt32(42) # ============================================================ @t.NoVTable class LLVMModuleCore: """模块/函数/值创建核心,封装 pool 避免每次创建都传 pool""" - Pool: memhub.MemBuddy | t.CPtr + Pool: rowptr[memhub.MemBuddy] - def __init__(self, pool: memhub.MemBuddy | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemBuddy]): self.Pool = pool # ---- 模块操作 ---- - def NewModule(self, name: t.CChar | t.CPtr) -> LLVMModule | t.CPtr: + def NewModule(self, name: str) -> rowptr[LLVMModule]: return new_module(self.Pool, name) - def CreateFunction(self, mod: LLVMModule | t.CPtr, name: t.CChar | t.CPtr, - ret_ty: LLVMType | t.CPtr) -> Function | t.CPtr: + def CreateFunction(self, mod: rowptr[LLVMModule], name: str, + ret_ty: rowptr[LLVMType]) -> rowptr[Function]: return create_function(self.Pool, mod, name, ret_ty) - def CreateDeclare(self, mod: LLVMModule | t.CPtr, name: t.CChar | t.CPtr, - ret_ty: LLVMType | t.CPtr) -> Function | t.CPtr: + def CreateDeclare(self, mod: rowptr[LLVMModule], name: str, + ret_ty: rowptr[LLVMType]) -> rowptr[Function]: """创建函数声明(declare,无函数体)""" return create_declare(self.Pool, mod, name, ret_ty) - def AddParam(self, func: Function | t.CPtr, ty: LLVMType | t.CPtr, - name: t.CChar | t.CPtr) -> Param | t.CPtr: + def AddParam(self, func: rowptr[Function], ty: rowptr[LLVMType], + name: str) -> rowptr[Param]: return add_param(self.Pool, func, ty, name) - def FunctionSetAttrs(self, func: Function | t.CPtr, attrs: t.CChar | t.CPtr): + def FunctionSetAttrs(self, func: rowptr[Function], attrs: str): """设置函数级属性文本""" function_set_attrs(func, attrs) - def ParamSetAttrs(self, param: Param | t.CPtr, attrs: t.CChar | t.CPtr): + def ParamSetAttrs(self, param: rowptr[Param], attrs: str): """设置参数属性文本""" param_set_attrs(param, attrs) - def CreateBlock(self, func: Function | t.CPtr, - name: t.CChar | t.CPtr) -> BasicBlock | t.CPtr: + def CreateBlock(self, func: rowptr[Function], + name: str) -> rowptr[BasicBlock]: return create_block(self.Pool, func, name) - def NewBuilder(self, func: Function | t.CPtr) -> IRBuilder | t.CPtr: + def NewBuilder(self, func: rowptr[Function]) -> rowptr[IRBuilder]: return new_builder(self.Pool, func) # ---- 全局变量 ---- - def NewGlobal(self, mod: LLVMModule | t.CPtr, name: t.CChar | t.CPtr, - ty: LLVMType | t.CPtr) -> GlobalVariable | t.CPtr: + def NewGlobal(self, mod: rowptr[LLVMModule], name: str, + ty: rowptr[LLVMType]) -> rowptr[GlobalVariable]: """创建全局变量并添加到模块""" - name_dup: t.CChar | t.CPtr = _str_dup(self.Pool, name) - gv: GlobalVariable | t.CPtr = new_global_variable(self.Pool, name_dup, ty) + name_dup: str = _str_dup(self.Pool, name) + gv: rowptr[GlobalVariable] = new_global_variable(self.Pool, name_dup, ty) if gv is not None: module_add_global(mod, gv) return gv - def CreateGlobalString(self, mod: LLVMModule | t.CPtr, name: t.CChar | t.CPtr, - text: t.CChar | t.CPtr) -> GlobalVariable | t.CPtr: + def CreateGlobalString(self, mod: rowptr[LLVMModule], name: str, + text: str) -> rowptr[GlobalVariable]: """创建字符串常量全局变量""" return create_global_string(self.Pool, mod, name, text) - def CreateGlobalInt(self, mod: LLVMModule | t.CPtr, name: t.CChar | t.CPtr, - bits: t.CInt, val: t.CInt64T) -> GlobalVariable | t.CPtr: + def CreateGlobalInt(self, mod: rowptr[LLVMModule], name: str, + bits: int, val: int64) -> rowptr[GlobalVariable]: """创建带初始化值的整数全局变量""" return create_global_int(self.Pool, mod, name, bits, val) - def GlobalSetConstant(self, gv: GlobalVariable | t.CPtr, is_const: t.CInt): + def GlobalSetConstant(self, gv: rowptr[GlobalVariable], is_const: int): global_set_constant(gv, is_const) - def GlobalSetLinkage(self, gv: GlobalVariable | t.CPtr, linkage: t.CChar | t.CPtr): + def GlobalSetLinkage(self, gv: rowptr[GlobalVariable], linkage: str): global_set_linkage(gv, linkage) - def GlobalSetUnnamedAddr(self, gv: GlobalVariable | t.CPtr, level: t.CInt): + def GlobalSetUnnamedAddr(self, gv: rowptr[GlobalVariable], level: int): global_set_unnamed_addr(gv, level) - def GlobalSetSection(self, gv: GlobalVariable | t.CPtr, section: t.CChar | t.CPtr): + def GlobalSetSection(self, gv: rowptr[GlobalVariable], section: str): global_set_section(gv, section) # ---- 值创建 ---- - def ConstInt(self, bits: t.CInt, val: t.CInt64T) -> Value | t.CPtr: + def ConstInt(self, bits: int, val: int64) -> rowptr[Value]: return const_int(self.Pool, bits, val) - def ConstInt32(self, val: t.CInt64T) -> Value | t.CPtr: + def ConstInt32(self, val: int64) -> rowptr[Value]: return const_int32(self.Pool, val) - def ConstInt64(self, val: t.CInt64T) -> Value | t.CPtr: + def ConstInt64(self, val: int64) -> rowptr[Value]: return const_int64(self.Pool, val) - def ConstFloat(self, ty: LLVMType | t.CPtr, val: t.CDouble) -> Value | t.CPtr: + def ConstFloat(self, ty: rowptr[LLVMType], val: t.CDouble) -> rowptr[Value]: return ConstFloat(self.Pool, ty, val) - def SSAValue(self, ty: LLVMType | t.CPtr, name: t.CChar | t.CPtr) -> Value | t.CPtr: + def SSAValue(self, ty: rowptr[LLVMType], name: str) -> rowptr[Value]: return SSAValue(self.Pool, ty, name) - def ConstNull(self, ty: LLVMType | t.CPtr, name: t.CChar | t.CPtr) -> Value | t.CPtr: + def ConstNull(self, ty: rowptr[LLVMType], name: str) -> rowptr[Value]: return ConstNull(self.Pool, ty, name) # ---- 打印 ---- - def PrintValue(self, buf: t.CChar | t.CPtr, size: t.CSizeT, val: Value | t.CPtr): + def PrintValue(self, buf: str, size: t.CSizeT, val: rowptr[Value]): ValuePrint(buf, size, val, self.Pool) - def PrintFunction(self, buf: t.CChar | t.CPtr, size: t.CSizeT, func: Function | t.CPtr): + def PrintFunction(self, buf: str, size: t.CSizeT, func: rowptr[Function]): FunctionPrint(buf, size, func, self.Pool) - def PrintModule(self, buf: t.CChar | t.CPtr, size: t.CSizeT, mod: LLVMModule | t.CPtr): + def PrintModule(self, buf: str, size: t.CSizeT, mod: rowptr[LLVMModule]): LLVMModulePrint(buf, size, mod, self.Pool, OUTPUT_FULL) # ---- SSA 验证 ---- - def NewVerifyResult(self, buf_size: t.CSizeT) -> VerifyResult | t.CPtr: + def NewVerifyResult(self, buf_size: t.CSizeT) -> rowptr[VerifyResult]: """创建验证结果对象(buf_size 为错误消息缓冲区大小)""" return _new_verify_result(self.Pool, buf_size) - def VerifyFunction(self, func: Function | t.CPtr, - result: VerifyResult | t.CPtr) -> t.CInt: + def VerifyFunction(self, func: rowptr[Function], + result: rowptr[VerifyResult]) -> int: """验证单个函数的 SSA 正确性,返回错误数(0=通过)""" return verify_function(self.Pool, func, result) - def VerifyModule(self, mod: LLVMModule | t.CPtr, - result: VerifyResult | t.CPtr) -> t.CInt: + def VerifyModule(self, mod: rowptr[LLVMModule], + result: rowptr[VerifyResult]) -> int: """验证模块中所有函数的 SSA 正确性,返回错误数(0=通过)""" return verify_module(self.Pool, mod, result) diff --git a/llvmlite/__module.vp b/llvmlite/__module.vp index df3c7fa..2a337c7 100644 --- a/llvmlite/__module.vp +++ b/llvmlite/__module.vp @@ -18,13 +18,14 @@ from .__function import Function, FunctionPrint, _ll_name_needs_quote, Param, pa # ============================================================ @t.NoVTable class GlobalVariable(GSListNode[GlobalVariable]): - Name: t.CChar | t.CPtr # 全局变量名(如 ".str" / "my_global") - Ty: LLVMType | t.CPtr # 变量类型 - Initializer: t.CVoid | t.CPtr # 初始化值 Value*(None = 无初始化) - IsConstant: t.CInt # 1=constant, 0=variable - Linkage: t.CChar | t.CPtr # 链接类型("private"/"internal"/"external"/...) - Section: t.CChar | t.CPtr # 段名(None = 默认) - UnnamedAddr: t.CInt # 1=unnamed_addr, 2=local_unnamed_addr, 0=none + Name: str # 全局变量名(如 ".str" / "my_global") + Ty: rowptr[LLVMType] # 变量类型 + Initializer: rowptr[t.CVoid] # 初始化值 Value*(None = 无初始化) + IsConstant: int # 1=constant, 0=variable + Linkage: str # 链接类型("private"/"internal"/"external"/...) + Section: str # 段名(None = 默认) + UnnamedAddr: int # 1=unnamed_addr, 2=local_unnamed_addr, 0=none + Align: int # 对齐字节数(0=默认对齐,如 @c.Attribute(t.attr.aligned(16))) # ============================================================ @@ -35,7 +36,8 @@ class GlobalVariable(GSListNode[GlobalVariable]): # ============================================================ @t.NoVTable class NamedTypeNode(GSListNode[NamedTypeNode]): - Ty: LLVMType | t.CPtr # 命名结构体类型指针 + Ty: rowptr[LLVMType] # 命名结构体类型指针 + IsPacked: int # 1=packed 结构体(输出 <{...}>,无字段填充) # ============================================================ @@ -48,17 +50,17 @@ class NamedTypeNode(GSListNode[NamedTypeNode]): # ============================================================ @t.NoVTable class LLVMModule: - Name: t.CChar | t.CPtr # 模块名 - FuncHead: Function | t.CPtr # 函数链表头 - FuncTail: Function | t.CPtr # 函数链表尾 + Name: str # 模块名 + FuncHead: rowptr[Function] # 函数链表头 + FuncTail: rowptr[Function] # 函数链表尾 FuncCount: t.CSizeT # 函数计数 - GlobalHead: GlobalVariable | t.CPtr # 全局变量链表头 - GlobalTail: GlobalVariable | t.CPtr # 全局变量链表尾 + GlobalHead: rowptr[GlobalVariable] # 全局变量链表头 + GlobalTail: rowptr[GlobalVariable] # 全局变量链表尾 GlobalCount: t.CSizeT # 全局变量计数 - TargetTriple: t.CChar | t.CPtr # 目标三元组(如 "x86_64-pc-linux-gnu") - DataLayout: t.CChar | t.CPtr # 数据布局(如 "e-m:e-p270:32:32-...") - NamedTypeHead: NamedTypeNode | t.CPtr # 命名结构体类型链表头 - NamedTypeTail: NamedTypeNode | t.CPtr # 命名结构体类型链表尾 + TargetTriple: str # 目标三元组(如 "x86_64-pc-linux-gnu") + DataLayout: str # 数据布局(如 "e-m:e-p270:32:32-...") + NamedTypeHead: rowptr[NamedTypeNode] # 命名结构体类型链表头 + NamedTypeTail: rowptr[NamedTypeNode] # 命名结构体类型链表尾 NamedTypeCount: t.CSizeT # 命名结构体类型计数 # 总计: 12 字段 * 8 = 96 字节(无 vtable) @@ -68,7 +70,7 @@ class LLVMModule: # ============================================================ # ---- 链表操作 ---- - def add_function(self, func: Function | t.CPtr): + def add_function(self, func: rowptr[Function]): """将函数追加到模块函数链表(O(1))""" if self is None or func is None: return func.Next = None @@ -79,7 +81,7 @@ class LLVMModule: self.FuncTail = func self.FuncCount += 1 - def add_global(self, gv: GlobalVariable | t.CPtr): + def add_global(self, gv: rowptr[GlobalVariable]): """将全局变量追加到模块全局变量链表(O(1))""" if self is None or gv is None: return gv.Next = None @@ -91,18 +93,18 @@ class LLVMModule: self.GlobalCount += 1 # ---- 目标属性 ---- - def set_target(self, triple: t.CChar | t.CPtr): + def set_target(self, triple: str): """设置目标三元组""" if self is None: return self.TargetTriple = triple - def set_datalayout(self, layout: t.CChar | t.CPtr): + def set_datalayout(self, layout: str): """设置数据布局""" if self is None: return self.DataLayout = layout # ---- 命名结构体类型管理 ---- - def add_named_type(self, pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr): + def add_named_type(self, pool: rowptr[memhub.MemBuddy], ty: rowptr[LLVMType]): """将命名结构体类型添加到模块(用于输出 %"name" = type { ... } 定义行) 非命名结构体(Name 为 None 或非 Struct 类型)会被忽略。 @@ -110,12 +112,12 @@ class LLVMModule: """ if self is None or pool is None or ty is None: return - name: t.CChar | t.CPtr = get_struct_name(ty) + name: str = get_struct_name(ty) if name is None: return # 去重检查(opaque 声明可被完整定义替换) - cur: NamedTypeNode | t.CPtr = self.NamedTypeHead - cnt_dedup: t.CInt = 0 + cur: rowptr[NamedTypeNode] = self.NamedTypeHead + cnt_dedup: int = 0 while cur is not None: # 步数守卫:NamedTypeHead 链表成环(内存损坏/插入 bug)会导致 # 无限遍历挂起(G3 编译 LinkedNode.prepend 挂起根因)。 @@ -126,7 +128,7 @@ class LLVMModule: name if name is not None else "(null)", cnt_dedup) stdlib.exit(1) if cur.Ty is not None: - existing_name: t.CChar | t.CPtr = get_struct_name(cur.Ty) + existing_name: str = get_struct_name(cur.Ty) if existing_name is not None: if string.strcmp(existing_name, name) == 0: # 已有完整定义则无需替换 @@ -140,11 +142,12 @@ class LLVMModule: return cur = cur.Next # 创建新节点 - node: NamedTypeNode | t.CPtr = pool.alloc(NAMED_TYPE_NODE_SIZE) + node: rowptr[NamedTypeNode] = pool.alloc(NAMED_TYPE_NODE_SIZE) if node is None: return string.memset(node, 0, NAMED_TYPE_NODE_SIZE) node.Ty = ty + node.IsPacked = 0 # opaque 类型插入链表头部,确保在引用它的完整定义之前声明。 # 例如 TypeRegistry{HashTable*, ...} 中,HashTable 的 opaque 声明 # 必须在 TypeRegistry 定义之前,否则 llc 报 "use of undefined type"。 @@ -163,12 +166,12 @@ class LLVMModule: self.NamedTypeTail = node self.NamedTypeCount += 1 - def _is_type_defined_in_module(self, name: t.CChar | t.CPtr) -> int: + def _is_type_defined_in_module(self, name: str) -> int: """检查模块中是否已定义指定名称的结构体类型,返回 1=已定义 / 0=未定义""" if self is None or name is None: return 0 - cur: NamedTypeNode | t.CPtr = self.NamedTypeHead - cnt_tdm: t.CInt = 0 + cur: rowptr[NamedTypeNode] = self.NamedTypeHead + cnt_tdm: int = 0 while cur is not None: # 步数守卫:同上,防 NamedTypeHead 链表成环无限遍历 cnt_tdm += 1 @@ -177,15 +180,15 @@ class LLVMModule: name if name is not None else "(null)") stdlib.exit(1) if cur.Ty is not None: - existing_name: t.CChar | t.CPtr = get_struct_name(cur.Ty) + existing_name: str = get_struct_name(cur.Ty) if existing_name is not None: if string.strcmp(existing_name, name) == 0: return 1 cur = cur.Next return 0 - def ensure_opaque_for_type(self, pool: memhub.MemBuddy | t.CPtr, - ty: LLVMType | t.CPtr): + def ensure_opaque_for_type(self, pool: rowptr[memhub.MemBuddy], + ty: rowptr[LLVMType]): """为类型中的跨模块结构体引用添加 opaque 声明 当类型引用了 Ptr(Struct(name)) 且 name 包含 '.'(SHA1 限定名)时, @@ -194,8 +197,8 @@ class LLVMModule: _scan_type_for_cross_module_refs(pool, self, ty) # ---- 打印 ---- - def PrintModule(self, buf: t.CChar | t.CPtr, size: t.CSizeT, - pool: memhub.MemBuddy | t.CPtr, mode: t.CInt): + def PrintModule(self, buf: str, size: t.CSizeT, + pool: rowptr[memhub.MemBuddy], mode: int): """将模块序列化为 .ll 文本写入 buf""" if self is None or buf is None or size == 0: return @@ -226,7 +229,7 @@ class LLVMModule: # 扫描所有函数签名,为跨模块结构体引用添加 opaque 定义 # 确保 stub.ll 包含被 declare/define 引用的跨模块类型定义 # 修复:alloc_buf 返回 viperio.Buf,但 Buf 类型未在 NamedTypeHead 中注册 - func_scan: Function | t.CPtr = self.FuncHead + func_scan: rowptr[Function] = self.FuncHead func_scan_steps: t.CSizeT = 0 while func_scan is not None: func_scan_steps += 1 @@ -237,7 +240,17 @@ class LLVMModule: if func_scan.RetTy is not None: self.ensure_opaque_for_type(pool, func_scan.RetTy) if func_scan.Params is not None: - param_scan: Param | t.CPtr = func_scan.Params.Head + # [DBGCHAIN] Function.Params 指针合理性护栏(临时诊断,用后移除) + fp_v: t.CUInt64T = t.CUInt64T(func_scan.Params) + if fp_v < 0x10000 or fp_v == t.CUInt64T(0xFFFFFFFFFFFFFFFF) or ((fp_v >> 56) & 0xFF) == 0xFF: + fnp: str = "(nil)" + if func_scan.Name is not None: + fnp = func_scan.Name + stdio.printf("[DBGCHAIN] Function.Params 野值: func=%s func=%llx steps=%zu Params=%llx FuncCount=%zu\n", + fnp, t.CUInt64T(func_scan), func_scan_steps, fp_v, t.CUInt64T(self.FuncCount)) + stdio.fflush(None) + stdlib.exit(1) + param_scan: rowptr[Param] = func_scan.Params.Head param_scan_steps: t.CSizeT = 0 while param_scan is not None: param_scan_steps += 1 @@ -246,6 +259,19 @@ class LLVMModule: func_scan.Name, func_scan.Params.Count, t.CUInt64T(param_scan), t.CUInt64T(param_scan.Next), IR_DUMP_CHAIN_LIMIT) stdlib.exit(1) + # [DBGCHAIN] param 指针合理性护栏(临时诊断,用后移除): + # 指针被写坏成小值/全 F 时先打印归属函数与链表状态,再退出 + pv_scan: t.CUInt64T = t.CUInt64T(param_scan) + pv_next: t.CUInt64T = 0 + if param_scan.Next is not None: + pv_next = t.CUInt64T(param_scan.Next) + if pv_scan < 0x10000 or pv_scan == t.CUInt64T(0xFFFFFFFFFFFFFFFF) or ((pv_scan >> 56) & 0xFF) == 0xFF: + stdio.printf("[DBGCHAIN] param 指针野值: func=%s steps=%zu param=%llx next=%llx Params.Head=%llx Params.Tail=%llx Params.Count=%zu\n", + func_scan.Name, param_scan_steps, pv_scan, pv_next, + t.CUInt64T(func_scan.Params.Head), t.CUInt64T(func_scan.Params.Tail), + t.CUInt64T(func_scan.Params.Count)) + stdio.fflush(None) + stdlib.exit(1) # 用访问器(__function.vp 完整类型内)绕开 stub 字段访问 # 陷阱:跨模块 struct 字段访问可能生成错误 GEP/静默跳过, # 导致 param_scan 永不更新死循环。 @@ -253,10 +279,10 @@ class LLVMModule: self.ensure_opaque_for_type(pool, param_get_ty(param_scan)) param_scan = param_get_next(param_scan) func_scan = func_scan.Next - nt: NamedTypeNode | t.CPtr = self.NamedTypeHead + nt: rowptr[NamedTypeNode] = self.NamedTypeHead # 结构体定义缓冲区:48 字段 × ~50 字节/字段类型名 ≈ 2400 字节,4096 足够 # 在循环外分配一次并复用,减少 pool 碎片 - ty_buf: t.CChar | t.CPtr = pool.alloc(4096) + ty_buf: str = pool.alloc(4096) nt_steps: t.CSizeT = 0 while nt is not None: nt_steps += 1 @@ -267,7 +293,7 @@ class LLVMModule: if nt.Ty is not None: if ty_buf is not None: ty_buf[0] = '\0' - PrintStructDefinition(ty_buf, 4096, nt.Ty, pool) + PrintStructDefinition(ty_buf, 4096, nt.Ty, pool, nt.IsPacked) _append_cstr(buf, size, ty_buf) _append_cstr(buf, size, "\n") nt = nt.Next @@ -276,7 +302,7 @@ class LLVMModule: _append_cstr(buf, size, "\n") # 全局变量 - gv: GlobalVariable | t.CPtr = self.GlobalHead + gv: rowptr[GlobalVariable] = self.GlobalHead gv_steps: t.CSizeT = 0 if mode == OUTPUT_STUB: # stub 模式:输出 external global(无初值) @@ -292,7 +318,7 @@ class LLVMModule: else: # full 和 text 模式:输出完整全局变量 # text 模式跳过无初值的全局变量(纯声明) - gv_idx: t.CInt = 0 + gv_idx: int = 0 while gv is not None: gv_steps += 1 if gv_steps > IR_DUMP_CHAIN_LIMIT: @@ -312,8 +338,8 @@ class LLVMModule: _append_cstr(buf, size, "\n") elif self.GlobalHead is not None and mode == OUTPUT_TEXT: # text 模式下如果输出了全局变量,也加空行 - had_global: t.CInt = 0 - gv2: GlobalVariable | t.CPtr = self.GlobalHead + had_global: int = 0 + gv2: rowptr[GlobalVariable] = self.GlobalHead gv2_steps: t.CSizeT = 0 while gv2 is not None: gv2_steps += 1 @@ -329,8 +355,8 @@ class LLVMModule: _append_cstr(buf, size, "\n") # 遍历函数 - func: Function | t.CPtr = self.FuncHead - func_idx: t.CInt = 0 + func: rowptr[Function] = self.FuncHead + func_idx: int = 0 func_steps: t.CSizeT = 0 while func is not None: func_steps += 1 @@ -359,10 +385,10 @@ class LLVMModule: # ============================================================ # 工厂函数 # ============================================================ -def new_module(pool: memhub.MemBuddy | t.CPtr, name: t.CChar | t.CPtr) -> LLVMModule | t.CPtr: +def new_module(pool: rowptr[memhub.MemBuddy], name: str) -> rowptr[LLVMModule]: """创建一个模块""" # 硬编码 96 字节:12 字段 * 8 字节(无 vtable,@t.NoVTable) - ptr: LLVMModule | t.CPtr = pool.alloc(96) + ptr: rowptr[LLVMModule] = pool.alloc(96) if ptr is None: return None string.memset(ptr, 0, 96) ptr.Name = name @@ -380,16 +406,16 @@ def new_module(pool: memhub.MemBuddy | t.CPtr, name: t.CChar | t.CPtr) -> LLVMMo return ptr -# GlobalVariable 硬编码大小: Next(8) + Name(8) + Ty(8) + Initializer(8) + IsConstant(4) + Linkage(8) + Section(8) + UnnamedAddr(4) = 64 字节 -GV_SIZE: t.CDefine = 64 +# GlobalVariable 硬编码大小: Next(8) + Name(8) + Ty(8) + Initializer(8) + IsConstant(4) + Linkage(8) + Section(8) + UnnamedAddr(4) + Align(4) = 72 字节 +GV_SIZE: t.CDefine = 72 -# NamedTypeNode 硬编码大小: Next(8) + Ty(8) = 16 字节 -NAMED_TYPE_NODE_SIZE: t.CDefine = 16 +# NamedTypeNode 硬编码大小: Next(8) + Ty(8) + IsPacked(8) = 24 字节 +NAMED_TYPE_NODE_SIZE: t.CDefine = 24 -def new_global_variable(pool: memhub.MemBuddy | t.CPtr, - name: t.CChar | t.CPtr, ty: LLVMType | t.CPtr) -> GlobalVariable | t.CPtr: +def new_global_variable(pool: rowptr[memhub.MemBuddy], + name: str, ty: rowptr[LLVMType]) -> rowptr[GlobalVariable]: """创建一个全局变量""" - ptr: GlobalVariable | t.CPtr = pool.alloc(GV_SIZE) + ptr: rowptr[GlobalVariable] = pool.alloc(GV_SIZE) if ptr is None: return None string.memset(ptr, 0, GV_SIZE) ptr.Name = name @@ -399,33 +425,34 @@ def new_global_variable(pool: memhub.MemBuddy | t.CPtr, ptr.Linkage = "external" ptr.Section = None ptr.UnnamedAddr = 0 + ptr.Align = 0 return ptr # ============================================================ # 链表操作(嵌入式 Head/Tail/Count,O(1) 追加) # ============================================================ -def module_add_function(mod: LLVMModule | t.CPtr, func: Function | t.CPtr): - return mod.add_function(func) +def module_add_function(mod: rowptr[LLVMModule], func: rowptr[Function]): + mod.add_function(func) -def module_get_func_head(mod: LLVMModule | t.CPtr) -> Function | t.CPtr: +def module_get_func_head(mod: rowptr[LLVMModule]) -> rowptr[Function]: """获取模块函数链表头(跨模块访问器,绕 stub 字段访问陷阱)""" if mod is None: return None return mod.FuncHead -def module_add_global(mod: LLVMModule | t.CPtr, gv: GlobalVariable | t.CPtr): - return mod.add_global(gv) +def module_add_global(mod: rowptr[LLVMModule], gv: rowptr[GlobalVariable]): + mod.add_global(gv) -def module_set_target(mod: LLVMModule | t.CPtr, triple: t.CChar | t.CPtr): - return mod.set_target(triple) +def module_set_target(mod: rowptr[LLVMModule], triple: str): + mod.set_target(triple) -def module_set_datalayout(mod: LLVMModule | t.CPtr, layout: t.CChar | t.CPtr): - return mod.set_datalayout(layout) +def module_set_datalayout(mod: rowptr[LLVMModule], layout: str): + mod.set_datalayout(layout) # ============================================================ @@ -444,7 +471,7 @@ def module_set_datalayout(mod: LLVMModule | t.CPtr, layout: t.CChar | t.CPtr): # # Returns: 1=是 opaque / 0=否 # ============================================================ -def _is_opaque_struct(ty: LLVMType | t.CPtr) -> int: +def _is_opaque_struct(ty: rowptr[LLVMType]) -> int: """检查类型是否是 opaque 结构体 opaque 是跨模块前向声明(仅名称无字段定义),由 @@ -466,9 +493,36 @@ def _is_opaque_struct(ty: LLVMType | t.CPtr) -> int: return 0 -def module_add_named_type(mod: LLVMModule | t.CPtr, pool: memhub.MemBuddy | t.CPtr, - ty: LLVMType | t.CPtr): - return mod.add_named_type(pool, ty) +def module_add_named_type(mod: rowptr[LLVMModule], pool: rowptr[memhub.MemBuddy], + ty: rowptr[LLVMType]): + mod.add_named_type(pool, ty) + + +def module_set_named_type_packed(mod: rowptr[LLVMModule], pool: rowptr[memhub.MemBuddy], + ty: rowptr[LLVMType], is_packed: int): + """按名称设置命名结构体的 packed 标记(输出 %"name" = type <{...}>)。 + + 编译器解析 @c.Attribute(t.attr.packed) 后调用,使 llc 按 packed 布局 + (无字段填充)计算字段偏移/GEP。ty 为命名 Struct 类型(按 get_struct_name + 定位已注册节点);未找到则静默跳过(opaque/跨模块 stub 场景无布局需求)。 + """ + if mod is None or ty is None: + return + name: str = get_struct_name(ty) + if name is None: + return + cur: rowptr[NamedTypeNode] = mod.NamedTypeHead + cnt_p: int = 0 + while cur is not None: + cnt_p += 1 + if cnt_p > 100000: + return + if cur.Ty is not None: + existing_name: str = get_struct_name(cur.Ty) + if existing_name is not None and string.strcmp(existing_name, name) == 0: + cur.IsPacked = is_packed + return + cur = cur.Next # ============================================================ @@ -478,14 +532,14 @@ def module_add_named_type(mod: LLVMModule | t.CPtr, pool: memhub.MemBuddy | t.CP # 如果该名称未在模块中定义,则添加 opaque 声明(%"name" = type opaque)。 # 这解决了跨模块结构体引用导致的 llc "use of undefined type" 错误。 # ============================================================ -def _is_type_defined_in_module(mod: LLVMModule | t.CPtr, name: t.CChar | t.CPtr) -> int: +def _is_type_defined_in_module(mod: rowptr[LLVMModule], name: str) -> int: return mod._is_type_defined_in_module(name) -def _scan_type_for_cross_module_refs(pool: memhub.MemBuddy | t.CPtr, - mod: LLVMModule | t.CPtr, - ty: LLVMType | t.CPtr, - depth: t.CInt = 0): +def _scan_type_for_cross_module_refs(pool: rowptr[memhub.MemBuddy], + mod: rowptr[LLVMModule], + ty: rowptr[LLVMType], + depth: int = 0): """递归扫描类型树,为跨模块结构体引用添加 opaque 声明""" if ty is None or mod is None or pool is None: return @@ -506,13 +560,13 @@ def _scan_type_for_cross_module_refs(pool: memhub.MemBuddy | t.CPtr, # 创建 opaque 类型并添加到模块 # fcount=-1 哨兵标记 opaque(区别于空结构体 {}, # 后者 fcount==0 是合法完整定义,可 alloca) - opaque_ty: LLVMType | t.CPtr = Struct(pool, None, -1, sname) + opaque_ty: rowptr[LLVMType] = Struct(pool, None, -1, sname) if opaque_ty is not None: module_add_named_type(mod, pool, opaque_ty) # 递归扫描结构体字段中的跨模块引用 # 例如 TypeRegistry{HashTable*, MemManager*} 中的 HashTable 引用 if sfields is not None: - fld: ParamNode | t.CPtr = sfields + fld: rowptr[ParamNode] = sfields fld_steps: t.CSizeT = 0 while fld is not None: fld_steps += 1 @@ -526,20 +580,9 @@ def _scan_type_for_cross_module_refs(pool: memhub.MemBuddy | t.CPtr, case _: _scan_type_for_cross_module_refs(pool, mod, pointee, depth + 1) case LLVMType.Struct(sfields2, sfcount2, sname2): - # 顶层结构体(非指针):递归扫描字段,并补 opaque 声明。 - # 此前只对 Ptr(Struct) 添加 opaque,裸 Struct(值类型,如 - # 数组元素 [7 x gdt_entry] 的 gdt_entry)引用时无任何类型定义 - # → llc "use of undefined type named 'sha1.gdt_entry'" - # (fpu/fat32 合并 IR external global 根因)。值类型引用 - # 同样需要类型存在(opaque 即可);模块已有完整定义时 - # _is_type_defined_in_module 命中,不重复添加。 - if sname2 is not None and string.strchr(sname2, 46) is not None: - if _is_type_defined_in_module(mod, sname2) == 0: - opaque_ty2: LLVMType | t.CPtr = Struct(pool, None, -1, sname2) - if opaque_ty2 is not None: - module_add_named_type(mod, pool, opaque_ty2) + # 顶层结构体(非指针):递归扫描字段 if sfields2 is not None: - fld2: ParamNode | t.CPtr = sfields2 + fld2: rowptr[ParamNode] = sfields2 fld2_steps: t.CSizeT = 0 while fld2 is not None: fld2_steps += 1 @@ -557,34 +600,34 @@ def _scan_type_for_cross_module_refs(pool: memhub.MemBuddy | t.CPtr, pass -def module_ensure_opaque_for_type(mod: LLVMModule | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, - ty: LLVMType | t.CPtr): - return mod.ensure_opaque_for_type(pool, ty) +def module_ensure_opaque_for_type(mod: rowptr[LLVMModule], + pool: rowptr[memhub.MemBuddy], + ty: rowptr[LLVMType]): + mod.ensure_opaque_for_type(pool, ty) # ============================================================ # 全局变量属性设置 # ============================================================ -def global_set_constant(gv: GlobalVariable | t.CPtr, is_const: t.CInt): +def global_set_constant(gv: rowptr[GlobalVariable], is_const: int): """设置全局变量是否为常量""" if gv is None: return gv.IsConstant = is_const -def global_set_linkage(gv: GlobalVariable | t.CPtr, linkage: t.CChar | t.CPtr): +def global_set_linkage(gv: rowptr[GlobalVariable], linkage: str): """设置链接类型 (private/internal/external/... )""" if gv is None: return gv.Linkage = linkage -def global_set_unnamed_addr(gv: GlobalVariable | t.CPtr, level: t.CInt): +def global_set_unnamed_addr(gv: rowptr[GlobalVariable], level: int): """设置 unnamed_addr 属性 (0=none, 1=unnamed_addr, 2=local_unnamed_addr)""" if gv is None: return gv.UnnamedAddr = level -def global_set_section(gv: GlobalVariable | t.CPtr, section: t.CChar | t.CPtr): +def global_set_section(gv: rowptr[GlobalVariable], section: str): """设置段名""" if gv is None: return gv.Section = section @@ -610,17 +653,17 @@ IR_DUMP_CHAIN_LIMIT: t.CDefine = 100000 # # mode: OUTPUT_FULL=完整, OUTPUT_STUB=仅声明, OUTPUT_TEXT=仅代码 # ============================================================ -def LLVMModulePrint(buf: t.CChar | t.CPtr, size: t.CSizeT, - mod: LLVMModule | t.CPtr, pool: memhub.MemBuddy | t.CPtr, - mode: t.CInt): - return mod.PrintModule(buf, size, pool, mode) +def LLVMModulePrint(buf: str, size: t.CSizeT, + mod: rowptr[LLVMModule], pool: rowptr[memhub.MemBuddy], + mode: int): + mod.PrintModule(buf, size, pool, mode) # ============================================================ # 全局变量打印 # ============================================================ -def _print_global(buf: t.CChar | t.CPtr, size: t.CSizeT, - gv: GlobalVariable | t.CPtr, pool: memhub.MemBuddy | t.CPtr): +def _print_global(buf: str, size: t.CSizeT, + gv: rowptr[GlobalVariable], pool: rowptr[memhub.MemBuddy]): """打印单个全局变量: @ = [linkage] [unnamed_addr] [constant] """ if gv is None: return @@ -655,7 +698,7 @@ def _print_global(buf: t.CChar | t.CPtr, size: t.CSizeT, _append_cstr(buf, size, "global ") # 类型 - ty_buf: t.CChar | t.CPtr = pool.alloc(512) + ty_buf: str = pool.alloc(512) if ty_buf is not None: ty_buf[0] = '\0' TypePrint(ty_buf, 512, gv.Ty, pool) @@ -672,12 +715,19 @@ def _print_global(buf: t.CChar | t.CPtr, size: t.CSizeT, _append_cstr(buf, size, gv.Section) _append_cstr(buf, size, "\"") + # 对齐(@c.Attribute(t.attr.aligned(N)) 类的全局实例,如 fpu_context 16 对齐) + if gv.Align > 0: + align_buf: str = pool.alloc(32) + if align_buf is not None: + viperlib.snprintf(align_buf, 32, ", align %d", gv.Align) + _append_cstr(buf, size, align_buf) + # ============================================================ # _print_global_stub - 打印全局变量的声明形式(external global,无初值) # ============================================================ -def _print_global_stub(buf: t.CChar | t.CPtr, size: t.CSizeT, - gv: GlobalVariable | t.CPtr, pool: memhub.MemBuddy | t.CPtr): +def _print_global_stub(buf: str, size: t.CSizeT, + gv: rowptr[GlobalVariable], pool: rowptr[memhub.MemBuddy]): """打印全局变量声明: @ = external global """ if gv is None: return @@ -692,7 +742,7 @@ def _print_global_stub(buf: t.CChar | t.CPtr, size: t.CSizeT, _append_cstr(buf, size, " = external global ") # 类型 - ty_buf: t.CChar | t.CPtr = pool.alloc(512) + ty_buf: str = pool.alloc(512) if ty_buf is not None: ty_buf[0] = '\0' TypePrint(ty_buf, 512, gv.Ty, pool) @@ -708,7 +758,7 @@ def _print_global_stub(buf: t.CChar | t.CPtr, size: t.CSizeT, _g_last_dst: t.CUInt64T = 0 _g_last_pos: t.CSizeT = 0 -def _append_cstr(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPtr): +def _append_cstr(dst: str, dst_size: t.CSizeT, src: str): """将 C 字符串 src 追加到 dst 末尾""" global _g_last_dst, _g_last_pos if dst is None or src is None: return diff --git a/llvmlite/__types.vp b/llvmlite/__types.vp index d3afb58..6bb8b9b 100644 --- a/llvmlite/__types.vp +++ b/llvmlite/__types.vp @@ -11,13 +11,13 @@ from linkedlist import GSListNode # ============================================================ # ParamNode: 函数参数类型链表节点 # 继承 GSListNode[ParamNode] 获取强类型 Next: ParamNode|CPtr -# Ty 用 t.CVoid | t.CPtr 前向引用,使用时转型为 (LLVMType | t.CPtr) +# Ty 用 rowptr[t.CVoid] 前向引用,使用时转型为 (rowptr[LLVMType]) # # 注意: 必须加 @t.NoVTable(理由见 __function.py 的 Line 注释)。 # ============================================================ @t.NoVTable class ParamNode(GSListNode[ParamNode]): - Ty: t.CVoid | t.CPtr # LLVMType*(前向引用,使用时转型) + Ty: rowptr[t.CVoid] # LLVMType*(前向引用,使用时转型) # ============================================================ @@ -29,34 +29,34 @@ class ParamNode(GSListNode[ParamNode]): class LLVMType(t.REnum): # 整数类型: i1/i8/i16/i32/i64 class Int: - Bits: t.CInt + Bits: int # 指针类型: pointee* class Ptr: - Pointee: LLVMType | t.CPtr + Pointee: rowptr[LLVMType] # 函数类型: ret (params) class Func: - Ret: LLVMType | t.CPtr - Params: ParamNode | t.CPtr - PCount: t.CInt + Ret: rowptr[LLVMType] + Params: rowptr[ParamNode] + PCount: int # 数组类型: [N x elem_ty] class Array: - ElemTy: LLVMType | t.CPtr - Count: t.CInt + ElemTy: rowptr[LLVMType] + Count: int # 结构体类型: {ty1, ty2, ...} 或 %"name" = type {ty1, ty2, ...} # Fields 复用 ParamNode 链表(ParamNode.Ty 即字段类型) # Name 非 None 时为命名结构体,TypePrint 输出 %"name" 而非 {...} class Struct: - Fields: ParamNode | t.CPtr - FCount: t.CInt - Name: t.CChar | t.CPtr + Fields: rowptr[ParamNode] + FCount: int + Name: str # 浮点类型: half/float/double/fp128 class Float: - Bits: t.CInt # 16=half, 32=float, 64=double, 128=fp128 + Bits: int # 16=half, 32=float, 64=double, 128=fp128 # 无值类型 class Void: @@ -74,9 +74,9 @@ class LLVMType(t.REnum): # ============================================================ # 内部分配辅助 # ============================================================ -def _new_type(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: +def _new_type(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: """从 mpool 分配一个零初始化的 LLVMType""" - ptr: LLVMType | t.CPtr = pool.alloc(LLVMType.__sizeof__()) + ptr: rowptr[LLVMType] = pool.alloc(LLVMType.__sizeof__()) if ptr: string.memset(ptr, 0, LLVMType.__sizeof__()) return ptr @@ -85,42 +85,42 @@ def _new_type(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: # ============================================================ # 类型工厂函数 # ============================================================ -def Int1(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: - ptr: LLVMType | t.CPtr = _new_type(pool) +def Int1(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Int(1)) return ptr -def Int8(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: - ptr: LLVMType | t.CPtr = _new_type(pool) +def Int8(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Int(8)) return ptr -def Int16(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: - ptr: LLVMType | t.CPtr = _new_type(pool) +def Int16(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Int(16)) return ptr -def Int32(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: - ptr: LLVMType | t.CPtr = _new_type(pool) +def Int32(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Int(32)) return ptr -def Int64(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: - ptr: LLVMType | t.CPtr = _new_type(pool) +def Int64(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Int(64)) return ptr -def Ptr(pool: memhub.MemBuddy | t.CPtr, pointee: LLVMType | t.CPtr) -> LLVMType | t.CPtr: +def Ptr(pool: rowptr[memhub.MemBuddy], pointee: rowptr[LLVMType]) -> rowptr[LLVMType]: """创建指针类型 Ptr(pointee) LLVM IR 中 **不允许 void* 指针**("pointers to void are invalid"), @@ -130,7 +130,7 @@ def Ptr(pool: memhub.MemBuddy | t.CPtr, pointee: LLVMType | t.CPtr) -> LLVMType 其他类型正常构造 Ptr(pointee)。 """ # ============== 前置校验: 拦截 Void / None pointee(void* 非法)============== - safe_pointee: LLVMType | t.CPtr = pointee + safe_pointee: rowptr[LLVMType] = pointee if safe_pointee is None: safe_pointee = Int8(pool) else: @@ -139,85 +139,85 @@ def Ptr(pool: memhub.MemBuddy | t.CPtr, pointee: LLVMType | t.CPtr) -> LLVMType safe_pointee = Int8(pool) case _: pass - ptr: LLVMType | t.CPtr = _new_type(pool) + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Ptr(safe_pointee)) return ptr -def Func(pool: memhub.MemBuddy | t.CPtr, ret: LLVMType | t.CPtr, - params: ParamNode | t.CPtr, count: t.CInt) -> LLVMType | t.CPtr: - ptr: LLVMType | t.CPtr = _new_type(pool) +def Func(pool: rowptr[memhub.MemBuddy], ret: rowptr[LLVMType], + params: rowptr[ParamNode], count: int) -> rowptr[LLVMType]: + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Func(ret, params, count)) return ptr -def Void(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: - ptr: LLVMType | t.CPtr = _new_type(pool) +def Void(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Void()) return ptr -def Array(pool: memhub.MemBuddy | t.CPtr, elem_ty: LLVMType | t.CPtr, - count: t.CInt) -> LLVMType | t.CPtr: +def Array(pool: rowptr[memhub.MemBuddy], elem_ty: rowptr[LLVMType], + count: int) -> rowptr[LLVMType]: """创建数组类型 [count x elem_ty]""" - ptr: LLVMType | t.CPtr = _new_type(pool) + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Array(elem_ty, count)) return ptr -def Struct(pool: memhub.MemBuddy | t.CPtr, fields: ParamNode | t.CPtr, - fcount: t.CInt, name: t.CChar | t.CPtr) -> LLVMType | t.CPtr: +def Struct(pool: rowptr[memhub.MemBuddy], fields: rowptr[ParamNode], + fcount: int, name: str) -> rowptr[LLVMType]: """创建结构体类型 {ty1, ty2, ...} fields 为 ParamNode 链表头,fcount 为字段数量。 name 非 None 时为命名结构体(如 "sha1.ClassName"),TypePrint 输出 %"name"。 name 为 None 时为匿名结构体,TypePrint 输出 {ty1, ty2, ...}。 """ - ptr: LLVMType | t.CPtr = _new_type(pool) + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Struct(fields, fcount, name)) return ptr -def Half(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: +def Half(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: """创建半精度浮点类型 half (16-bit)""" - ptr: LLVMType | t.CPtr = _new_type(pool) + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Float(16)) return ptr -def Float(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: +def Float(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: """创建单精度浮点类型 float (32-bit)""" - ptr: LLVMType | t.CPtr = _new_type(pool) + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Float(32)) return ptr -def Double(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: +def Double(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: """创建双精度浮点类型 double (64-bit)""" - ptr: LLVMType | t.CPtr = _new_type(pool) + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Float(64)) return ptr -def FP128(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: +def FP128(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: """创建四精度浮点类型 fp128 (128-bit)""" - ptr: LLVMType | t.CPtr = _new_type(pool) + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Float(128)) return ptr -def Label(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: +def Label(pool: rowptr[memhub.MemBuddy]) -> rowptr[LLVMType]: """创建标签类型 label""" - ptr: LLVMType | t.CPtr = _new_type(pool) + ptr: rowptr[LLVMType] = _new_type(pool) if ptr is None: return None c.DerefAs(ptr, LLVMType.Label()) return ptr @@ -229,9 +229,9 @@ def Label(pool: memhub.MemBuddy | t.CPtr) -> LLVMType | t.CPtr: # ParamNode 硬编码大小: Next(8) + Ty(8) = 16 字节 PNODE_SIZE: t.CDefine = 16 -def new_param_node(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr) -> ParamNode | t.CPtr: +def new_param_node(pool: rowptr[memhub.MemBuddy], ty: rowptr[LLVMType]) -> rowptr[ParamNode]: """创建一个参数节点,Ty 设为给定类型指针""" - ptr: ParamNode | t.CPtr = pool.alloc(PNODE_SIZE) + ptr: rowptr[ParamNode] = pool.alloc(PNODE_SIZE) if ptr is None: return None string.memset(ptr, 0, PNODE_SIZE) ptr.Ty = ty @@ -239,8 +239,8 @@ def new_param_node(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr) -> Par return ptr -def param_list_append(head: ParamNode | t.CPtr, tail: ParamNode | t.CPtr, - node: ParamNode | t.CPtr) -> ParamNode | t.CPtr: +def param_list_append(head: rowptr[ParamNode], tail: rowptr[ParamNode], + node: rowptr[ParamNode]) -> rowptr[ParamNode]: """将 node 追加到参数链表尾部,返回 head 和更新后的 tail""" if node is None: return head node.Next = None @@ -258,28 +258,28 @@ def param_list_append(head: ParamNode | t.CPtr, tail: ParamNode | t.CPtr, # 导致 TransPyC 静默跳过字段访问。这些访问器在拥有完整类型定义的 # 本模块内执行,能正确访问所有字段。 # ============================================================ -def paramnode_get_ty(node: ParamNode | t.CPtr) -> LLVMType | t.CPtr: +def paramnode_get_ty(node: rowptr[ParamNode]) -> rowptr[LLVMType]: """获取参数节点的类型""" if node is None: return None - return (LLVMType | t.CPtr)(node.Ty) + return (rowptr[LLVMType])(node.Ty) -def paramnode_get_next(node: ParamNode | t.CPtr) -> ParamNode | t.CPtr: +def paramnode_get_next(node: rowptr[ParamNode]) -> rowptr[ParamNode]: """获取链表下一个参数节点""" if node is None: return None return node.Next -def paramnode_set_ty(node: ParamNode | t.CPtr, ty: LLVMType | t.CPtr): +def paramnode_set_ty(node: rowptr[ParamNode], ty: rowptr[LLVMType]): """设置参数节点的类型""" if node is None: return node.Ty = ty -def paramnode_set_next(node: ParamNode | t.CPtr, nxt: ParamNode | t.CPtr): +def paramnode_set_next(node: rowptr[ParamNode], nxt: rowptr[ParamNode]): """设置链表下一个参数节点""" if node is None: return @@ -290,77 +290,77 @@ def paramnode_set_next(node: ParamNode | t.CPtr, nxt: ParamNode | t.CPtr): # LLVMTypeCore: 类型创建核心,封装 pool 避免重复传参 # # 用法: -# core: LLVMTypeCore | t.CPtr = LLVMTypeCore(pool) -# ty_i32: LLVMType | t.CPtr = core.Int32() -# ty_ptr: LLVMType | t.CPtr = core.Ptr(ty_i32) -# ty_void: LLVMType | t.CPtr = core.Void() +# core: rowptr[LLVMTypeCore] = LLVMTypeCore(pool) +# ty_i32: rowptr[LLVMType] = core.Int32() +# ty_ptr: rowptr[LLVMType] = core.Ptr(ty_i32) +# ty_void: rowptr[LLVMType] = core.Void() # ============================================================ @t.NoVTable class LLVMTypeCore: """类型创建核心,封装 pool 避免每次创建类型都传 pool""" - Pool: memhub.MemBuddy | t.CPtr + Pool: rowptr[memhub.MemBuddy] - def __init__(self, pool: memhub.MemBuddy | t.CPtr): + def __init__(self, pool: rowptr[memhub.MemBuddy]): self.Pool = pool - def Int1(self) -> LLVMType | t.CPtr: + def Int1(self) -> rowptr[LLVMType]: return Int1(self.Pool) - def Int8(self) -> LLVMType | t.CPtr: + def Int8(self) -> rowptr[LLVMType]: return Int8(self.Pool) - def Int16(self) -> LLVMType | t.CPtr: + def Int16(self) -> rowptr[LLVMType]: return Int16(self.Pool) - def Int32(self) -> LLVMType | t.CPtr: + def Int32(self) -> rowptr[LLVMType]: return Int32(self.Pool) - def Int64(self) -> LLVMType | t.CPtr: + def Int64(self) -> rowptr[LLVMType]: return Int64(self.Pool) - def Ptr(self, pointee: LLVMType | t.CPtr) -> LLVMType | t.CPtr: + def Ptr(self, pointee: rowptr[LLVMType]) -> rowptr[LLVMType]: return Ptr(self.Pool, pointee) - def Func(self, ret: LLVMType | t.CPtr, params: ParamNode | t.CPtr, - count: t.CInt) -> LLVMType | t.CPtr: + def Func(self, ret: rowptr[LLVMType], params: rowptr[ParamNode], + count: int) -> rowptr[LLVMType]: return Func(self.Pool, ret, params, count) - def Array(self, elem_ty: LLVMType | t.CPtr, count: t.CInt) -> LLVMType | t.CPtr: + def Array(self, elem_ty: rowptr[LLVMType], count: int) -> rowptr[LLVMType]: return Array(self.Pool, elem_ty, count) - def Struct(self, fields: ParamNode | t.CPtr, fcount: t.CInt, - name: t.CChar | t.CPtr = None) -> LLVMType | t.CPtr: + def Struct(self, fields: rowptr[ParamNode], fcount: int, + name: str = None) -> rowptr[LLVMType]: return Struct(self.Pool, fields, fcount, name) - def Void(self) -> LLVMType | t.CPtr: + def Void(self) -> rowptr[LLVMType]: return Void(self.Pool) - def Half(self) -> LLVMType | t.CPtr: + def Half(self) -> rowptr[LLVMType]: return Half(self.Pool) - def Float(self) -> LLVMType | t.CPtr: + def Float(self) -> rowptr[LLVMType]: return Float(self.Pool) - def Double(self) -> LLVMType | t.CPtr: + def Double(self) -> rowptr[LLVMType]: return Double(self.Pool) - def FP128(self) -> LLVMType | t.CPtr: + def FP128(self) -> rowptr[LLVMType]: return FP128(self.Pool) - def Label(self) -> LLVMType | t.CPtr: + def Label(self) -> rowptr[LLVMType]: return Label(self.Pool) - def NewParamNode(self, ty: LLVMType | t.CPtr) -> ParamNode | t.CPtr: + def NewParamNode(self, ty: rowptr[LLVMType]) -> rowptr[ParamNode]: return new_param_node(self.Pool, ty) # ---- 链表辅助 ---- - def ParamListAppend(self, head: ParamNode | t.CPtr, tail: ParamNode | t.CPtr, - node: ParamNode | t.CPtr) -> ParamNode | t.CPtr: + def ParamListAppend(self, head: rowptr[ParamNode], tail: rowptr[ParamNode], + node: rowptr[ParamNode]) -> rowptr[ParamNode]: """将 node 追加到参数/字段链表,返回新的 tail""" return param_list_append(head, tail, node) # ---- 打印 ---- - def PrintType(self, buf: t.CChar | t.CPtr, size: t.CSizeT, ty: LLVMType | t.CPtr): + def PrintType(self, buf: str, size: t.CSizeT, ty: rowptr[LLVMType]): TypePrint(buf, size, ty, self.Pool) @@ -378,8 +378,8 @@ class LLVMTypeCore: # # pool 用于复杂类型(Array/Struct/Func)递归打印子类型时分配临时缓冲区。 # ============================================================ -def TypePrint(buf: t.CChar | t.CPtr, size: t.CSizeT, - ty: LLVMType | t.CPtr, pool: memhub.MemBuddy | t.CPtr): +def TypePrint(buf: str, size: t.CSizeT, + ty: rowptr[LLVMType], pool: rowptr[memhub.MemBuddy]): """将类型 ty 序列化为 IR 文本写入 buf(容量 size) pool 用于递归打印子类型时分配临时缓冲区。 @@ -392,9 +392,9 @@ def TypePrint(buf: t.CChar | t.CPtr, size: t.CSizeT, # 造成 OOM(单文件暴涨 900MB 根因)。超过 100 层即停止打印。 TYPEPRINT_MAX_DEPTH: t.CDefine = 100 -def _TypePrintDepth(buf: t.CChar | t.CPtr, size: t.CSizeT, - ty: LLVMType | t.CPtr, pool: memhub.MemBuddy | t.CPtr, - depth: t.CInt): +def _TypePrintDepth(buf: str, size: t.CSizeT, + ty: rowptr[LLVMType], pool: rowptr[memhub.MemBuddy], + depth: int): """带递归深度上限的 TypePrint 内部实现""" if ty is None or buf is None or size == 0: return @@ -422,7 +422,7 @@ def _TypePrintDepth(buf: t.CChar | t.CPtr, size: t.CSizeT, # 类型名含 sha1 前缀可超 40 字符(如 # "bbdf3bbd4c3bc28c.CONSOLE_SCREEN_BUFFER_INFO"=42), # 原 40 字节截断会产生未定义类型引用(llc: undefined type)。 - sn_cp: t.CChar | t.CPtr = pool.alloc(256) + sn_cp: str = pool.alloc(256) if sn_cp is not None: string.strncpy(sn_cp, sname, 255) sn_cp[255] = '\0' @@ -455,7 +455,7 @@ def _TypePrintDepth(buf: t.CChar | t.CPtr, size: t.CSizeT, viperlib.snprintf(buf, size, "[%d x ", count) # SHA1 限定类型名(如 %"21a7fcfc665f75ef.NamedTypeNode")可达 ~50 字节, # 嵌套指针/数组更易超过 128,使用 512 字节避免截断 - tmp: t.CChar | t.CPtr = pool.alloc(512) + tmp: str = pool.alloc(512) if tmp is not None: _TypePrintDepth(tmp, 512, elem_ty, pool, depth + 1) _strappend(buf, size, tmp) @@ -471,11 +471,11 @@ def _TypePrintDepth(buf: t.CChar | t.CPtr, size: t.CSizeT, # ret (ty1, ty2, ...) _TypePrintDepth(buf, size, ret, pool, depth + 1) _strappend(buf, size, " (") - cur2: ParamNode | t.CPtr = params - first2: t.CInt = 1 - _pc2: t.CInt = 0 + cur2: rowptr[ParamNode] = params + first2: int = 1 + _pc2: int = 0 # 函数参数类型可能为 SHA1 限定命名结构体指针,512 字节避免截断 - tmp3: t.CChar | t.CPtr = pool.alloc(512) + tmp3: str = pool.alloc(512) while cur2 is not None: # 悬空保护:参数链若被 reset 回收后内容复用,可能成环无限循环 _pc2 += 1 @@ -514,7 +514,7 @@ def _TypePrintDepth(buf: t.CChar | t.CPtr, size: t.CSizeT, # ============================================================ # 内部辅助 # ============================================================ -def _strappend(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPtr): +def _strappend(dst: str, dst_size: t.CSizeT, src: str): """将 src 追加到 dst 末尾(不超过 dst_size)""" if dst is None or src is None: return dlen: t.CSizeT = string.strlen(dst) @@ -537,25 +537,32 @@ def _strappend(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPtr) # # 供 TypePrint(匿名结构体)和 PrintStructDefinition(命名结构体定义行)复用 # ============================================================ -def _print_struct_body(buf: t.CChar | t.CPtr, size: t.CSizeT, - fields: ParamNode | t.CPtr, pool: memhub.MemBuddy | t.CPtr, - depth: t.CInt = 0): +def _print_struct_body(buf: str, size: t.CSizeT, + fields: rowptr[ParamNode], pool: rowptr[memhub.MemBuddy], + depth: int = 0, packed: int = 0): """打印 {ty1, ty2, ...} 到 buf(追加模式,不覆盖已有内容) 直接在 buf 当前末尾写入字段类型,避免 pool.alloc 返回与 buf 重叠的内存 导致 TypePrint 写入 tmp 时覆盖 buf 已有内容。 + packed=1 时输出 <{ty1, ty2, ...}>(LLVM packed struct,无字段填充)。 """ if buf is None or size == 0: return - _strappend(buf, size, "{") - cur: ParamNode | t.CPtr = fields - first: t.CInt = 1 - fidx: t.CInt = 0 + if packed != 0: + _strappend(buf, size, "<{") + else: + _strappend(buf, size, "{") + cur: rowptr[ParamNode] = fields + first: int = 1 + fidx: int = 0 while cur is not None: # 悬空保护:ParamNode 链若被 reset 回收后内容复用,Next 指针可能成环或 # 指向垃圾,无限循环。最多打印 200 个字段即停止,防止 OOM。 if fidx >= 200: - _strappend(buf, size, "...}") + if packed != 0: + _strappend(buf, size, "...}>") + else: + _strappend(buf, size, "...}") return if first == 0: _strappend(buf, size, ", ") @@ -567,7 +574,10 @@ def _print_struct_body(buf: t.CChar | t.CPtr, size: t.CSizeT, cur = cur.Next first = 0 fidx += 1 - _strappend(buf, size, "}") + if packed != 0: + _strappend(buf, size, "}>") + else: + _strappend(buf, size, "}") # ============================================================ @@ -576,12 +586,14 @@ def _print_struct_body(buf: t.CChar | t.CPtr, size: t.CSizeT, # 输出格式: %"name" = type { ty1, ty2, ... } # 供 LLVMModulePrint 在全局变量/函数之前输出类型定义 # ============================================================ -def PrintStructDefinition(buf: t.CChar | t.CPtr, size: t.CSizeT, - ty: LLVMType | t.CPtr, pool: memhub.MemBuddy | t.CPtr): +def PrintStructDefinition(buf: str, size: t.CSizeT, + ty: rowptr[LLVMType], pool: rowptr[memhub.MemBuddy], + packed: int = 0): """打印命名结构体类型定义行 %"name" = type { ty1, ty2, ... } 当 fcount == -1(哨兵)时输出 opaque 声明: %"name" = type opaque。 空结构体(fcount==0, fields==None,无字段类)是完整定义,输出 "= type {}"。 + packed=1 时输出 %"name" = type <{ ty1, ty2, ... }>(LLVM packed struct)。 """ if ty is None or buf is None or size == 0: return @@ -595,7 +607,7 @@ def PrintStructDefinition(buf: t.CChar | t.CPtr, size: t.CSizeT, viperlib.snprintf(buf, size, "%%\"%s\" = type opaque", name) else: viperlib.snprintf(buf, size, "%%\"%s\" = type ", name) - _print_struct_body(buf, size, fields, pool) + _print_struct_body(buf, size, fields, pool, 0, packed) case _: return @@ -606,7 +618,7 @@ def PrintStructDefinition(buf: t.CChar | t.CPtr, size: t.CSizeT, # 返回 Name 字段(如 "sha1.ClassName"),非 Struct 类型或匿名 Struct 返回 None # 供 module_add_named_type 检查是否为命名结构体及去重 # ============================================================ -def get_struct_name(ty: LLVMType | t.CPtr) -> t.CChar | t.CPtr: +def get_struct_name(ty: rowptr[LLVMType]) -> str: """获取命名结构体的名称,非命名结构体返回 None""" if ty is None: return None @@ -617,7 +629,7 @@ def get_struct_name(ty: LLVMType | t.CPtr) -> t.CChar | t.CPtr: return None -def get_struct_fields(ty: LLVMType | t.CPtr) -> ParamNode | t.CPtr: +def get_struct_fields(ty: rowptr[LLVMType]) -> rowptr[ParamNode]: """获取结构体的字段链表(供跨模块重建 Struct 类型用)""" if ty is None: return None @@ -628,7 +640,7 @@ def get_struct_fields(ty: LLVMType | t.CPtr) -> ParamNode | t.CPtr: return None -def get_struct_fcount(ty: LLVMType | t.CPtr) -> t.CInt: +def get_struct_fcount(ty: rowptr[LLVMType]) -> int: """获取结构体的字段数量(供跨模块重建 Struct 类型用)""" if ty is None: return 0 @@ -656,14 +668,14 @@ def get_struct_fcount(ty: LLVMType | t.CPtr) -> t.CInt: # ============================================================ DEEPCOPY_MAX_DEPTH: t.CDefine = 64 -def DeepCopyType(pool: memhub.MemBuddy | t.CPtr, - ty: LLVMType | t.CPtr) -> LLVMType | t.CPtr: +def DeepCopyType(pool: rowptr[memhub.MemBuddy], + ty: rowptr[LLVMType]) -> rowptr[LLVMType]: """深拷贝 LLVMType 到 stdlib 区(深度限制防自引用递归),失败返回 None""" return _DeepCopyDepth(pool, ty, 0) -def _DeepCopyDepth(pool: memhub.MemBuddy | t.CPtr, - ty: LLVMType | t.CPtr, depth: t.CInt) -> LLVMType | t.CPtr: +def _DeepCopyDepth(pool: rowptr[memhub.MemBuddy], + ty: rowptr[LLVMType], depth: int) -> rowptr[LLVMType]: """带深度上限的深拷贝实现 分配源用传入的 pool 参数(调用方决定):传主 pool 为瞬时拷贝 @@ -672,7 +684,7 @@ def _DeepCopyDepth(pool: memhub.MemBuddy | t.CPtr, """ if ty is None: return None - new_ty: LLVMType | t.CPtr = (LLVMType | t.CPtr)(pool.alloc(LLVMType.__sizeof__())) + new_ty: rowptr[LLVMType] = (rowptr[LLVMType])(pool.alloc(LLVMType.__sizeof__())) if new_ty is None: return None string.memset(new_ty, 0, LLVMType.__sizeof__()) @@ -716,25 +728,28 @@ def _DeepCopyDepth(pool: memhub.MemBuddy | t.CPtr, _DeepCopyParamChain(pool, fields, depth + 1), fcount, _DeepCopyStr(pool, name))) case _: - stdlib.free(new_ty) + # new_ty 由 pool(MemBuddy)分配,必须用 pool.free(buddy 回收) + # 而非 stdlib.free(仅回收 malloc 块)——后者对 arena 内指针调用 + # 会损坏堆(0xC0000374 / ASan bad-free)。 + pool.free(new_ty) return None return new_ty -def _DeepCopyParamChain(pool: memhub.MemBuddy | t.CPtr, - head: ParamNode | t.CPtr, depth: t.CInt) -> ParamNode | t.CPtr: +def _DeepCopyParamChain(pool: rowptr[memhub.MemBuddy], + head: rowptr[ParamNode], depth: int) -> rowptr[ParamNode]: """深拷贝 ParamNode 链表到 stdlib""" if head is None: return None - first: ParamNode | t.CPtr = None - prev: ParamNode | t.CPtr = None - cur: ParamNode | t.CPtr = head - guard: t.CInt = 0 + first: rowptr[ParamNode] = None + prev: rowptr[ParamNode] = None + cur: rowptr[ParamNode] = head + guard: int = 0 while cur is not None: guard += 1 if guard > 512: break - node: ParamNode | t.CPtr = (ParamNode | t.CPtr)(pool.alloc(PNODE_SIZE)) + node: rowptr[ParamNode] = (rowptr[ParamNode])(pool.alloc(PNODE_SIZE)) if node is None: break string.memset(node, 0, PNODE_SIZE) @@ -749,12 +764,12 @@ def _DeepCopyParamChain(pool: memhub.MemBuddy | t.CPtr, return first -def _DeepCopyStr(pool: memhub.MemBuddy | t.CPtr, s: t.CChar | t.CPtr) -> t.CChar | t.CPtr: +def _DeepCopyStr(pool: rowptr[memhub.MemBuddy], s: str) -> str: """深拷贝字符串到 stdlib""" if s is None: return None slen: t.CSizeT = string.strlen(s) - copy: t.CChar | t.CPtr = pool.alloc(slen + 1) + copy: str = pool.alloc(slen + 1) if copy is None: return None string.strcpy(copy, s) diff --git a/llvmlite/__values.vp b/llvmlite/__values.vp index f488587..0e40f0e 100644 --- a/llvmlite/__values.vp +++ b/llvmlite/__values.vp @@ -19,10 +19,10 @@ from .__types import LLVMType, TypePrint # ============================================================ @t.NoVTable class Value(GSListNode[Value]): - Ty: LLVMType | t.CPtr # 值的类型 - Name: t.CChar | t.CPtr # SSA 名("%0"/"%result")或常量文本("42"/"1.5e+00") - IsConst: t.CInt # 1=常量字面量, 0=SSA 临时值 - IntVal: t.CInt64T # 整数常量值(当 IsConst=1 时使用) + Ty: rowptr[LLVMType] # 值的类型 + Name: str # SSA 名("%0"/"%result")或常量文本("42"/"1.5e+00") + IsConst: int # 1=常量字面量, 0=SSA 临时值 + IntVal: int64 # 整数常量值(当 IsConst=1 时使用) FloatVal: t.CDouble # 浮点常量值(当 IsConst=1 且 Ty 为 Float 时使用) @@ -32,16 +32,16 @@ class Value(GSListNode[Value]): # Value 硬编码大小: Next(8) + Ty(8) + Name(8) + IsConst(4) + IntVal(8) + FloatVal(8) = 48 字节 VALUE_SIZE: t.CDefine = 48 -def new_value(pool: memhub.MemBuddy | t.CPtr) -> Value | t.CPtr: +def new_value(pool: rowptr[memhub.MemBuddy]) -> rowptr[Value]: """从 mpool 分配一个零初始化的 Value""" - ptr: Value | t.CPtr = pool.alloc(VALUE_SIZE) + ptr: rowptr[Value] = pool.alloc(VALUE_SIZE) if ptr: string.memset(ptr, 0, VALUE_SIZE) return ptr -def ConstInt(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, - val: t.CInt64T, name: t.CChar | t.CPtr) -> Value | t.CPtr: +def ConstInt(pool: rowptr[memhub.MemBuddy], ty: rowptr[LLVMType], + val: int64, name: str) -> rowptr[Value]: """创建整数常量值 参数: @@ -49,7 +49,7 @@ def ConstInt(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, val: 整数值 name: 常量文本(如 "42"),由调用方提供 """ - v: Value | t.CPtr = new_value(pool) + v: rowptr[Value] = new_value(pool) if v is None: return None v.Ty = ty v.Name = name @@ -58,10 +58,10 @@ def ConstInt(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, return v -def ConstNull(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, - name: t.CChar | t.CPtr) -> Value | t.CPtr: +def ConstNull(pool: rowptr[memhub.MemBuddy], ty: rowptr[LLVMType], + name: str) -> rowptr[Value]: """创建 null 指针常量""" - v: Value | t.CPtr = new_value(pool) + v: rowptr[Value] = new_value(pool) if v is None: return None v.Ty = ty v.Name = name @@ -70,9 +70,9 @@ def ConstNull(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, return v -def ConstZero(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr) -> Value | t.CPtr: +def ConstZero(pool: rowptr[memhub.MemBuddy], ty: rowptr[LLVMType]) -> rowptr[Value]: """创建 zeroinitializer 常量(零初始化聚合类型:结构体/数组)""" - v: Value | t.CPtr = new_value(pool) + v: rowptr[Value] = new_value(pool) if v is None: return None v.Ty = ty v.Name = "zeroinitializer" @@ -81,8 +81,8 @@ def ConstZero(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr) -> Value | return v -def ConstFloat(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, - val: t.CDouble) -> Value | t.CPtr: +def ConstFloat(pool: rowptr[memhub.MemBuddy], ty: rowptr[LLVMType], + val: t.CDouble) -> rowptr[Value]: """创建浮点常量值 参数: @@ -90,7 +90,7 @@ def ConstFloat(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, val: 浮点数值 名字自动格式化为 LLVM IR 科学计数法文本(如 "1.500000e+00")。 """ - v: Value | t.CPtr = new_value(pool) + v: rowptr[Value] = new_value(pool) if v is None: return None v.Ty = ty v.IsConst = 1 @@ -102,13 +102,13 @@ def ConstFloat(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, # 导致 add_scalar[0]==11 等浮点常量比较失败)。位模式无精度损失。 # 原 %e 默认 6 位小数还会截断精度(3.1415926535897931 -> 3.141593e+00)。 # 用 CRT stdio.snprintf: viperlib 自实现 %g 有小数位反转 bug。 - f_bits: t.CInt = 64 + f_bits: int = 64 match ty: case LLVMType.Float(ftb): f_bits = ftb fv_bits: t.CUInt64T = 0 c.Load(c.Addr(fv_bits), c.Addr(val)) - name_buf: t.CChar | t.CPtr = pool.alloc(32) + name_buf: str = pool.alloc(32) if name_buf is not None: if f_bits == 32: stdio.snprintf(name_buf, 32, "0x%08x", t.CUInt32T(fv_bits)) @@ -118,15 +118,15 @@ def ConstFloat(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, return v -def SSAValue(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, - name: t.CChar | t.CPtr) -> Value | t.CPtr: +def SSAValue(pool: rowptr[memhub.MemBuddy], ty: rowptr[LLVMType], + name: str) -> rowptr[Value]: """创建 SSA 临时值 参数: ty: 值类型 name: SSA 名(如 "%0"/"%result"),由调用方提供 """ - v: Value | t.CPtr = new_value(pool) + v: rowptr[Value] = new_value(pool) if v is None: return None v.Ty = ty v.Name = name @@ -142,8 +142,8 @@ def SSAValue(pool: memhub.MemBuddy | t.CPtr, ty: LLVMType | t.CPtr, # ConstInt(i32, 42, "42") -> "i32 42" # SSAValue(i32, "%0") -> "i32 %0" # ============================================================ -def ValuePrint(buf: t.CChar | t.CPtr, size: t.CSizeT, - val: Value | t.CPtr, pool: memhub.MemBuddy | t.CPtr): +def ValuePrint(buf: str, size: t.CSizeT, + val: rowptr[Value], pool: rowptr[memhub.MemBuddy]): """将值 val 序列化为 IR 文本写入 buf 格式: @@ -171,42 +171,42 @@ def ValuePrint(buf: t.CChar | t.CPtr, size: t.CSizeT, # 导致 TransPyC 静默跳过字段访问(不生成 GEP,不报错)。 # 这些访问器在拥有完整类型定义的本模块内执行,能正确访问所有字段。 # ============================================================ -def value_get_ty(val: Value | t.CPtr) -> LLVMType | t.CPtr: +def value_get_ty(val: rowptr[Value]) -> rowptr[LLVMType]: """获取值的类型""" if val is None: return None return val.Ty -def value_get_next(val: Value | t.CPtr) -> Value | t.CPtr: +def value_get_next(val: rowptr[Value]) -> rowptr[Value]: """获取链表下一个值""" if val is None: return None return val.Next -def value_set_ty(val: Value | t.CPtr, ty: LLVMType | t.CPtr): +def value_set_ty(val: rowptr[Value], ty: rowptr[LLVMType]): """设置值的类型""" if val is None: return val.Ty = ty -def value_set_next(val: Value | t.CPtr, nxt: Value | t.CPtr): +def value_set_next(val: rowptr[Value], nxt: rowptr[Value]): """设置链表下一个值""" if val is None: return val.Next = nxt -def value_set_name(val: Value | t.CPtr, name: t.CChar | t.CPtr): +def value_set_name(val: rowptr[Value], name: str): """设置值的名字""" if val is None: return val.Name = name -def value_set_isconst(val: Value | t.CPtr, is_const: t.CInt): +def value_set_isconst(val: rowptr[Value], is_const: int): """设置是否为常量""" if val is None: return @@ -216,7 +216,7 @@ def value_set_isconst(val: Value | t.CPtr, is_const: t.CInt): # ============================================================ # 内部辅助 # ============================================================ -def _append_str(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPtr): +def _append_str(dst: str, dst_size: t.CSizeT, src: str): """将 src 追加到 dst 末尾""" if dst is None or src is None: return dlen: t.CSizeT = string.strlen(dst) diff --git a/llvmlite/__verify.vp b/llvmlite/__verify.vp index 04f7733..6431592 100644 --- a/llvmlite/__verify.vp +++ b/llvmlite/__verify.vp @@ -33,33 +33,33 @@ VERIFY_ERR_PHI_NOT_FIRST: t.CDefine = 4 # ============================================================ @t.NoVTable class NameEntry(GSListNode[NameEntry]): - Name: t.CChar | t.CPtr # SSA 名(如 "%0"/"%result") + Name: str # SSA 名(如 "%0"/"%result") # ============================================================ # VerifyResult: 验证结果 # ============================================================ class VerifyResult: - ErrorCount: t.CInt # 错误总数 - WarningCount: t.CInt # 警告总数 - ErrorCode: t.CInt # 第一个错误码 - ErrorBuf: t.CChar | t.CPtr # 错误消息缓冲区 + ErrorCount: int # 错误总数 + WarningCount: int # 警告总数 + ErrorCode: int # 第一个错误码 + ErrorBuf: str # 错误消息缓冲区 ErrorBufSize: t.CSizeT # 缓冲区大小 # ============================================================ # 辅助函数 # ============================================================ -def _new_verify_result(pool: memhub.MemBuddy | t.CPtr, - buf_size: t.CSizeT) -> VerifyResult | t.CPtr: +def _new_verify_result(pool: rowptr[memhub.MemBuddy], + buf_size: t.CSizeT) -> rowptr[VerifyResult]: """创建验证结果对象""" - ptr: VerifyResult | t.CPtr = pool.alloc(VerifyResult.__sizeof__()) + ptr: rowptr[VerifyResult] = pool.alloc(VerifyResult.__sizeof__()) if ptr is None: return None string.memset(ptr, 0, VerifyResult.__sizeof__()) ptr.ErrorCount = 0 ptr.WarningCount = 0 ptr.ErrorCode = VERIFY_OK - buf: t.CChar | t.CPtr = pool.alloc(buf_size) + buf: str = pool.alloc(buf_size) if buf is not None: buf[0] = '\0' ptr.ErrorBuf = buf @@ -67,7 +67,7 @@ def _new_verify_result(pool: memhub.MemBuddy | t.CPtr, return ptr -def _report_error(result: VerifyResult | t.CPtr, code: t.CInt, msg: t.CChar | t.CPtr): +def _report_error(result: rowptr[VerifyResult], code: int, msg: str): """记录一个错误""" if result is None: return result.ErrorCount += 1 @@ -84,7 +84,7 @@ def _report_error(result: VerifyResult | t.CPtr, code: t.CInt, msg: t.CChar | t. _g_last_dst: t.CUInt64T = 0 _g_last_pos: t.CSizeT = 0 -def _append_cstr(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPtr): +def _append_cstr(dst: str, dst_size: t.CSizeT, src: str): """将 src 追加到 dst 末尾""" global _g_last_dst, _g_last_pos if dst is None or src is None: return @@ -115,9 +115,9 @@ def _append_cstr(dst: t.CChar | t.CPtr, dst_size: t.CSizeT, src: t.CChar | t.CPt # ============================================================ # SSA 名表操作 # ============================================================ -def _new_name_table(pool: memhub.MemBuddy | t.CPtr) -> GSList[NameEntry] | t.CPtr: +def _new_name_table(pool: rowptr[memhub.MemBuddy]) -> rowptr[GSList[NameEntry]]: """创建空名表""" - gsl: GSList[NameEntry] | t.CPtr = pool.alloc(24) # GSList: Head+Tail+Count + gsl: rowptr[GSList[NameEntry]] = pool.alloc(24) # GSList: Head+Tail+Count if gsl is None: return None string.memset(gsl, 0, 24) return gsl @@ -126,19 +126,19 @@ def _new_name_table(pool: memhub.MemBuddy | t.CPtr) -> GSList[NameEntry] | t.CPt # NameEntry 硬编码大小: Next(8) + Name(8) = 16 字节 NENTRY_SIZE: t.CDefine = 16 -def _name_table_add(table: GSList[NameEntry] | t.CPtr, - pool: memhub.MemBuddy | t.CPtr, - name: t.CChar | t.CPtr) -> t.CInt: +def _name_table_add(table: rowptr[GSList[NameEntry]], + pool: rowptr[memhub.MemBuddy], + name: str) -> int: """添加名到表。返回 1=重复, 0=成功添加""" if table is None or name is None: return 0 # 检查重复 - cur: NameEntry | t.CPtr = table.Head + cur: rowptr[NameEntry] = table.Head while cur is not None: if string.strcmp(cur.Name, name) == 0: return 1 cur = cur.Next # 添加新条目 - entry: NameEntry | t.CPtr = pool.alloc(NENTRY_SIZE) + entry: rowptr[NameEntry] = pool.alloc(NENTRY_SIZE) if entry is None: return 0 string.memset(entry, 0, NENTRY_SIZE) entry.Name = name @@ -146,11 +146,11 @@ def _name_table_add(table: GSList[NameEntry] | t.CPtr, return 0 -def _name_table_contains(table: GSList[NameEntry] | t.CPtr, - name: t.CChar | t.CPtr) -> t.CInt: +def _name_table_contains(table: rowptr[GSList[NameEntry]], + name: str) -> int: """检查名是否在表中。返回 1=存在, 0=不存在""" if table is None or name is None: return 0 - cur: NameEntry | t.CPtr = table.Head + cur: rowptr[NameEntry] = table.Head while cur is not None: if string.strcmp(cur.Name, name) == 0: return 1 @@ -161,7 +161,7 @@ def _name_table_contains(table: GSList[NameEntry] | t.CPtr, # ============================================================ # 文本分析辅助 # ============================================================ -def _is_char_name(ch: t.CChar) -> t.CInt: +def _is_char_name(ch: t.CChar) -> int: """判断字符是否为 SSA 名字符 [a-zA-Z0-9._]""" if ch >= 'a' and ch <= 'z': return 1 if ch >= 'A' and ch <= 'Z': return 1 @@ -170,8 +170,8 @@ def _is_char_name(ch: t.CChar) -> t.CInt: return 0 -def _extract_def_name(pool: memhub.MemBuddy | t.CPtr, - text: t.CChar | t.CPtr) -> t.CChar | t.CPtr: +def _extract_def_name(pool: rowptr[memhub.MemBuddy], + text: str) -> str: """从定义行提取被定义的 SSA 名。 定义行格式: "% = " @@ -180,14 +180,14 @@ def _extract_def_name(pool: memhub.MemBuddy | t.CPtr, if text is None: return None if text[0] != '%': return None # 扫描 " = " 模式 - i: t.CInt = 1 + i: int = 1 while text[i] != '\0': if text[i] == ' ' and text[i + 1] == '=' and text[i + 2] == ' ': # 找到 " = " 在位置 i - name_len: t.CInt = i - name: t.CChar | t.CPtr = pool.alloc(name_len + 1) + name_len: int = i + name: str = pool.alloc(name_len + 1) if name is None: return None - j: t.CInt = 0 + j: int = 0 while j < name_len: name[j] = text[j] j += 1 @@ -197,7 +197,7 @@ def _extract_def_name(pool: memhub.MemBuddy | t.CPtr, return None -def _is_terminator(text: t.CChar | t.CPtr) -> t.CInt: +def _is_terminator(text: str) -> int: """判断文本是否为终止指令""" if text is None: return 0 if string.strncmp(text, "ret", 3) == 0: return 1 @@ -209,32 +209,32 @@ def _is_terminator(text: t.CChar | t.CPtr) -> t.CInt: return 0 -def _is_phi(text: t.CChar | t.CPtr) -> t.CInt: +def _is_phi(text: str) -> int: """判断文本是否为 phi 指令""" if text is None: return 0 if string.strstr(text, " = phi ") is not None: return 1 return 0 -def _check_uses_in_line(table: GSList[NameEntry] | t.CPtr, - text: t.CChar | t.CPtr, - def_name: t.CChar | t.CPtr) -> t.CInt: +def _check_uses_in_line(table: rowptr[GSList[NameEntry]], + text: str, + def_name: str) -> int: """检查行中所有 SSA 名使用是否已定义。 跳过 def_name(定义位置的名字)。 返回未定义使用数量。 """ if text is None: return 0 - i: t.CInt = 0 - undef_count: t.CInt = 0 + i: int = 0 + undef_count: int = 0 while text[i] != '\0': if text[i] == '%': # 提取名 - name_start: t.CInt = i + name_start: int = i i += 1 while text[i] != '\0' and _is_char_name(text[i]) == 1: i += 1 - name_len: t.CInt = i - name_start + name_len: int = i - name_start if name_len > 1: # 构建临时名串进行比较 # 由于无法在栈上分配,用 strstr 进行简化检查 @@ -251,13 +251,13 @@ def _check_uses_in_line(table: GSList[NameEntry] | t.CPtr, return undef_count -def _name_matches_at(text: t.CChar | t.CPtr, start: t.CInt, length: t.CInt, - table: GSList[NameEntry] | t.CPtr) -> t.CInt: +def _name_matches_at(text: str, start: int, length: int, + table: rowptr[GSList[NameEntry]]) -> int: """检查 text[start:start+length] 是否匹配名表中的某个条目。 返回 1=匹配, 0=不匹配 """ if table is None: return 0 - cur: NameEntry | t.CPtr = table.Head + cur: rowptr[NameEntry] = table.Head while cur is not None: if cur.Name is not None: if _str_matches_at(text, start, length, cur.Name) == 1: @@ -266,16 +266,16 @@ def _name_matches_at(text: t.CChar | t.CPtr, start: t.CInt, length: t.CInt, return 0 -def _str_matches_at(text: t.CChar | t.CPtr, start: t.CInt, length: t.CInt, - target: t.CChar | t.CPtr) -> t.CInt: +def _str_matches_at(text: str, start: int, length: int, + target: str) -> int: """检查 text[start:start+length] 是否等于 target 字符串。 返回 1=匹配, 0=不匹配 """ if text is None or target is None: return 0 # 检查 target 长度 - target_len: t.CInt = string.strlen(target) + target_len: t.CSizeT = string.strlen(target) if target_len != length: return 0 - i: t.CInt = 0 + i: t.CSizeT = 0 while i < length: if text[start + i] != target[i]: return 0 i += 1 @@ -285,9 +285,9 @@ def _str_matches_at(text: t.CChar | t.CPtr, start: t.CInt, length: t.CInt, # ============================================================ # 主验证函数 # ============================================================ -def verify_function(pool: memhub.MemBuddy | t.CPtr, - func: Function | t.CPtr, - result: VerifyResult | t.CPtr) -> t.CInt: +def verify_function(pool: rowptr[memhub.MemBuddy], + func: rowptr[Function], + result: rowptr[VerifyResult]) -> int: """验证函数的 SSA 正确性。 参数: @@ -300,11 +300,11 @@ def verify_function(pool: memhub.MemBuddy | t.CPtr, if func is None or result is None: return 1 # 创建名表 - name_table: GSList[NameEntry] | t.CPtr = _new_name_table(pool) + name_table: rowptr[GSList[NameEntry]] = _new_name_table(pool) if name_table is None: return 1 # 1. 将函数参数加入名表(参数是已定义的) - param: Param | t.CPtr = None + param: rowptr[Param] = None if func.Params is not None: param = func.Params.Head while param is not None: @@ -313,13 +313,13 @@ def verify_function(pool: memhub.MemBuddy | t.CPtr, param = param.Next # 1b. 将基本块名加入名表(块标签如 %then 是 br/phi 的合法引用目标) - blk_iter: BasicBlock | t.CPtr = None + blk_iter: rowptr[BasicBlock] = None if func.Blocks is not None: blk_iter = func.Blocks.Head while blk_iter is not None: if blk_iter.Name is not None: blk_name_len: t.CSizeT = string.strlen(blk_iter.Name) - blk_ref: t.CChar | t.CPtr = pool.alloc(blk_name_len + 2) + blk_ref: str = pool.alloc(blk_name_len + 2) if blk_ref is not None: # 构造 "%" 字符串 blk_ref[0] = '%' @@ -332,15 +332,15 @@ def verify_function(pool: memhub.MemBuddy | t.CPtr, blk_iter = blk_iter.Next # 2. 遍历所有块 - blk: BasicBlock | t.CPtr = None + blk: rowptr[BasicBlock] = None if func.Blocks is not None: blk = func.Blocks.Head while blk is not None: # 检查终止指令 if blk.IsTerminated == 0: # 进一步检查最后一行是否为终止指令 - has_term: t.CInt = 0 - line_check: Line | t.CPtr = None + has_term: int = 0 + line_check: rowptr[Line] = None if blk.Lines is not None: line_check = blk.Lines.Head while line_check is not None: @@ -349,27 +349,27 @@ def verify_function(pool: memhub.MemBuddy | t.CPtr, has_term = 1 line_check = line_check.Next if has_term == 0: - blk_name: t.CChar | t.CPtr = "" + blk_name: str = "" if blk.Name is not None: blk_name = blk.Name - err_buf: t.CChar | t.CPtr = pool.alloc(128) + err_buf: str = pool.alloc(128) if err_buf is not None: viperlib.snprintf(err_buf, 128, "ERROR: block '%s' missing terminator", blk_name) _report_error(result, VERIFY_ERR_NO_TERMINATOR, err_buf) # 遍历块内指令行 - seen_non_phi: t.CInt = 0 - line: Line | t.CPtr = None + seen_non_phi: int = 0 + line: rowptr[Line] = None if blk.Lines is not None: line = blk.Lines.Head while line is not None: if line.Buf is not None: - text: t.CChar | t.CPtr = line.Buf + text: str = line.Buf # 检查 phi 位置 if _is_phi(text) == 1: if seen_non_phi == 1: - phi_err: t.CChar | t.CPtr = pool.alloc(128) + phi_err: str = pool.alloc(128) if phi_err is not None: viperlib.snprintf(phi_err, 128, "ERROR: phi not at block start") _report_error(result, VERIFY_ERR_PHI_NOT_FIRST, phi_err) @@ -379,20 +379,20 @@ def verify_function(pool: memhub.MemBuddy | t.CPtr, seen_non_phi = 1 # 提取定义名 - def_name: t.CChar | t.CPtr = _extract_def_name(pool, text) + def_name: str = _extract_def_name(pool, text) if def_name is not None: # 检查重复定义 - dup: t.CInt = _name_table_add(name_table, pool, def_name) + dup: int = _name_table_add(name_table, pool, def_name) if dup == 1: - dup_err: t.CChar | t.CPtr = pool.alloc(128) + dup_err: str = pool.alloc(128) if dup_err is not None: viperlib.snprintf(dup_err, 128, "ERROR: duplicate definition '%s'", def_name) _report_error(result, VERIFY_ERR_DUPLICATE_DEF, dup_err) # 检查未定义使用 - undef: t.CInt = _check_uses_in_line(name_table, text, def_name) + undef: int = _check_uses_in_line(name_table, text, def_name) if undef > 0: - use_err: t.CChar | t.CPtr = pool.alloc(128) + use_err: str = pool.alloc(128) if use_err is not None: viperlib.snprintf(use_err, 128, "ERROR: %d undefined use(s) in: %s", undef, text) _report_error(result, VERIFY_ERR_UNDEFINED_USE, use_err) @@ -404,13 +404,13 @@ def verify_function(pool: memhub.MemBuddy | t.CPtr, return result.ErrorCount -def verify_module(pool: memhub.MemBuddy | t.CPtr, mod: LLVMModule | t.CPtr, result: VerifyResult | t.CPtr) -> t.CInt: +def verify_module(pool: rowptr[memhub.MemBuddy], mod: rowptr[LLVMModule], result: rowptr[VerifyResult]) -> int: """验证模块中所有函数的 SSA 正确性。 返回: 错误总数 """ if mod is None or result is None: return 1 - func: Function | t.CPtr = mod.FuncHead + func: rowptr[Function] = mod.FuncHead while func is not None: if func.IsDeclared == 0: # 只验证有函数体的定义,跳过声明 diff --git a/memhub.vp b/memhub.vp index b02dd72..59b79b8 100644 --- a/memhub.vp +++ b/memhub.vp @@ -18,12 +18,12 @@ import stdlib MEMHUB_ALIGN: t.CDefine = 8 # MemSlab bitmap constants -MEMSLAB_MIN_BLOCK: t.CDefine = 16 +MEMSLAB_MIN_BLOCK: t.CDefine = 16 MEMSLAB_BITMAP_BYTES: t.CDefine = 256 # MemBuddy buddy constants -MEMBUDDY_MIN_BLOCK: t.CDefine = 32 -MEMBUDDY_MAX_ORDERS: t.CDefine = 32 +MEMBUDDY_MIN_BLOCK: t.CDefine = 32 +MEMBUDDY_MAX_ORDERS: t.CDefine = 32 MEMBUDDY_HEADER_SIZE: t.CDefine = 8 # 块尾 canary:alloc 时在块尾(用户数据区之外)写 8 字节哨兵, # check_alive_blocks 校验——越界写穿数据区会破坏 canary,把 @@ -34,7 +34,7 @@ MEMBUDDY_CANARY: t.CDefine = 8 # alloc 时把用户数据区填充 0xCD 哨兵。若对象初始化(list.__init__ 等) # 未执行,其字段保持 0xCDCD...,CTORDBG/VDBG 打印字段时一眼可辨 # "未初始化(0xCDCD)" 与 "被覆盖(其他值)"。0=关闭(性能),1=开启。 -MEMBUDDY_FILL_GUARD: t.CDefine = 1 +MEMBUDDY_FILL_GUARD: t.CDefine = 1 MEMBUDDY_FILL_PATTERN: t.CDefine = 0xCD # [DET] 分配检测(alloc 前后 2 字节 0xCDCD 标记 + 记录表探测越界写): @@ -51,7 +51,15 @@ MEMBUDDY_DET_RECORD_SIZE: t.CDefine = 33554432 # 记录追加本身 O(1) 不受影响;损坏是持久性的,不依赖即时扫描,采样 # 不损失检测能力——2M 次 alloc 若每次全表 O(n) 扫描 = O(n²) 太慢 # (用户反馈 detection 模式过慢),采样把扫描次数降为 1/N。 -MEMBUDDY_DET_PROBE_PERIOD: t.CDefine = 256 +MEMBUDDY_DET_PROBE_PERIOD: t.CDefine = 32 + +# [MEMDBG] 临时插桩(2026-09-04,定位 free list 重复 put / 悬空 free / alloc +# 重复出块;定位后整体移除,勿长期保留)。改动点: +# 1. alloc:采样分支内校验"新出块仍残留于同 order free list"; +# 2. free :归还前校验"同 order free list 已含本块"(double-put 实锤); +# 3. free :无效/悬空指针(池内但 header 偶数=已释放)不再静默忽略; +# 4. 既有 [DET]/[MEM] 终止路径补 stdio.fflush(None)(stdout 重定向丢输出)。 +MEMBUDDY_DBG: t.CDefine = 1 def _canary_pattern() -> t.CUInt64T: @@ -88,30 +96,30 @@ def _block_size_at_order(order: t.CInt) -> t.CSizeT: @t.CVTable class MemManager: __provides__: list[str] = ['__memmgr__'] - base: t.CVoid | t.CPtr # Starting address of memory region + base: t.CPtr # Starting address of memory region size: t.CSizeT # Total size of memory region - def __init__(self, base: t.CVoid | t.CPtr, size: t.CSizeT): + def __init__(self, base: t.CPtr, size: t.CSizeT): self.base = base self.size = size # === Virtual functions (overridden by subclasses) === - def alloc(self, size: t.CSizeT) -> t.CVoid | t.CPtr: + def alloc(self, size: t.CSizeT) -> t.CPtr: # Default: allocation not supported return None - def free(self, ptr: t.CVoid | t.CPtr) -> t.CInt: + def free(self, ptr: t.CPtr) -> int: # Default: no operation return 0 - def reset(self) -> t.CInt: + def reset(self) -> int: # Default: no operation return 0 # === Concrete methods (invoke virtual functions for automatic polymorphic dispatch) === - def calloc(self, count: t.CSizeT, size: t.CSizeT) -> t.CVoid | t.CPtr: + def calloc(self, count: t.CSizeT, size: t.CSizeT) -> t.CPtr: total: t.CSizeT = count * size ptr: t.CVoid | t.CPtr = self.alloc(total) if ptr is not None: @@ -418,16 +426,18 @@ class MemBuddy(MemManager): rem -= blk self.usable_size = used_area - # [DET] 分配检测记录区:stdlib.malloc 独立分配(不占用 buddy 区, + # 分配记录区:stdlib.malloc 独立分配(不占用 buddy 区, # 与 chk_stack 同策略)。容量 = detection_size // 16(每条 {ptr,size})。 - if detection != 0: - det_arena: t.CVoid | t.CPtr = t.CVoid( - stdlib.malloc(self.detection_size), t.CPtr) - if det_arena is not None: - self._det_arena = det_arena - self._det_records = (t.CUInt64T | t.CPtr)(t.CVoid(det_arena, t.CPtr)) - self._det_cap = self.detection_size // 16 - self._det_count = 0 + # 2026-09-04:记录+重叠检测从 detection 解耦——非 detection 也分配 + # 记录区并启用同地址重复分配检测(不做前后标记、不改 alloc 布局), + # 定位 free-list/重复分配类损坏(memhub 翻译早期容器 Count 槽被写坏)。 + det_arena: t.CVoid | t.CPtr = t.CVoid( + stdlib.malloc(self.detection_size), t.CPtr) + if det_arena is not None: + self._det_arena = det_arena + self._det_records = (t.CUInt64T | t.CPtr)(t.CVoid(det_arena, t.CPtr)) + self._det_cap = self.detection_size // 16 + self._det_count = 0 # === Checkpoint support === @@ -487,7 +497,10 @@ class MemBuddy(MemManager): # free 只置标志不删),截断 chk_depth 必须同步截断 _det_count, # 否则 reset 后旧记录仍标 active → 下一轮 alloc 复用同一块被 # 误报为"分配重叠/越界写"(SlotsBugTest 7B buf + 72B Token 误报根因)。 - if self.detection != 0 and self._det_records is not None: + # 2026-09-04 记录表已与 detection 解耦(detection=0 也启用记录+重叠 + # 检测),截断条件不能挂 detection——否则检测模式下 reset_to 后 + # 旧记录残留 active,复用块被误报重叠(记录[647] sz=72 误报例)。 + if self._det_records is not None: self._det_count = mark self._unlock() @@ -668,54 +681,80 @@ class MemBuddy(MemManager): if self.chk_depth < self.chk_cap: self.chk_stack[self.chk_depth] = t.CUInt64T(block) self.chk_depth += 1 - if result is not None and self.detection != 0: - # [DET] 布局 [0xCDCD][请求大小内存][0xCDCD]:返回指针 = 用户区 + 2 - # (前标记之后);记录 {返回 ptr, size} 到独立记录区;随后探测全部 - # 存活块的后标记——被破坏 = 越界写,立即汇报并终止。 + if result is not None and self._det_records is not None: base_ret_d: t.CUInt64T = t.CUInt64T(result) - m_f_d: t.CUInt16T | t.CPtr = (t.CUInt16T | t.CPtr)(t.CVoid(base_ret_d, t.CPtr)) - m_f_d[0] = t.CUInt16T(MEMBUDDY_DET_MARKER) - tail_d: t.CUInt64T = base_ret_d + 2 + t.CUInt64T(size) - m_t_d: t.CUInt16T | t.CPtr = (t.CUInt16T | t.CPtr)(t.CVoid(tail_d, t.CPtr)) - m_t_d[0] = t.CUInt16T(MEMBUDDY_DET_MARKER) - if self._det_records is not None: - # 采样:每 MEMBUDDY_DET_PROBE_PERIOD 次 alloc 做一次全表扫描 - # (分配重叠 + 探测),其余只追加记录(O(1))。损坏是持久性的, - # 不依赖即时扫描——2M 次 alloc 若每次全表 O(n) = O(n²) 太慢 - # (用户反馈 detection 模式过慢),采样把扫描降为 O(n²/PERIOD)。 - if (self._det_count & (MEMBUDDY_DET_PROBE_PERIOD - 1)) == 0: - # 分配重叠即时检测:新块地址是否已在 active 记录(同一块重复 - # 分配实锤——SlotsBugTest 7B buf 与 72B Token 同 ptr、cargs - # 只写 0/40 根因)。重叠 = MemBuddy free list 损坏(active 块 - # 混入 free list),在第一次重叠处拦截并打印两个 size。 - ff_d: t.CUInt64T = t.CUInt64T(1) << 63 - dup_i: t.CSizeT = 0 - while dup_i < self._det_count: - drp: t.CUInt64T = self._det_records[dup_i * 2] - drs: t.CUInt64T = self._det_records[dup_i * 2 + 1] - if drp == base_ret_d + 2 and (drs & ff_d) == 0: - stdio.printf("[DET] 分配重叠: 新alloc(size=%llu)与记录[%zu](sz=%llu)同地址 ptr=%llu(同一块重复分配,free list 损坏)\n", - t.CUInt64T(size), dup_i, drs & (ff_d - 1), base_ret_d + 2) + # 返回指针(detection 布局下 = 用户区 + 2,前标记之后) + rec_ptr_d: t.CUInt64T = base_ret_d + if self.detection != 0: + # [DET] 布局 [0xCDCD][请求大小内存][0xCDCD]:返回指针 = 用户区 + 2 + # (前标记之后);记录 {返回 ptr, size} 到独立记录区;随后探测全部 + # 存活块的后标记——被破坏 = 越界写,立即汇报并终止。 + m_f_d: t.CUInt16T | t.CPtr = (t.CUInt16T | t.CPtr)(t.CVoid(base_ret_d, t.CPtr)) + m_f_d[0] = t.CUInt16T(MEMBUDDY_DET_MARKER) + tail_d: t.CUInt64T = base_ret_d + 2 + t.CUInt64T(size) + m_t_d: t.CUInt16T | t.CPtr = (t.CUInt16T | t.CPtr)(t.CVoid(tail_d, t.CPtr)) + m_t_d[0] = t.CUInt16T(MEMBUDDY_DET_MARKER) + rec_ptr_d = base_ret_d + 2 + # 采样:每 MEMBUDDY_DET_PROBE_PERIOD 次 alloc 做一次全表扫描 + # (分配重叠 + 探测),其余只追加记录(O(1))。损坏是持久性的, + # 不依赖即时扫描——2M 次 alloc 若每次全表 O(n) = O(n²) 太慢 + # (用户反馈 detection 模式过慢),采样把扫描降为 O(n²/PERIOD)。 + if (self._det_count & (MEMBUDDY_DET_PROBE_PERIOD - 1)) == 0: + # 分配重叠即时检测:新块地址是否已在 active 记录(同一块重复 + # 分配实锤——SlotsBugTest 7B buf 与 72B Token 同 ptr、cargs + # 只写 0/40 根因)。重叠 = MemBuddy free list 损坏(active 块 + # 混入 free list),在第一次重叠处拦截并打印两个 size。 + ff_d: t.CUInt64T = t.CUInt64T(1) << 63 + dup_i: t.CSizeT = 0 + while dup_i < self._det_count: + drp: t.CUInt64T = self._det_records[dup_i * 2] + drs: t.CUInt64T = self._det_records[dup_i * 2 + 1] + if drp == rec_ptr_d and (drs & ff_d) == 0: + stdio.printf("[DET] 分配重叠: 新alloc(size=%llu)与记录[%zu](sz=%llu)同地址 ptr=%llu(同一块重复分配,free list 损坏)\n", + t.CUInt64T(size), dup_i, drs & (ff_d - 1), rec_ptr_d) + stdio.fflush(None) + stdlib.exit(1) + dup_i += 1 + if MEMBUDDY_DBG != 0: + # [MEMDBG] 新出块是否仍残留于同 order free list(此前的重复 put + # 使链表含两条本块 → pop 后还有残条 → 本块将被二次分配,双向写穿)。 + # 记录表重叠检测要等下次 pop 同地址才撞见,这里在出块当场提前拦截。 + dbg_block: t.CVoid | t.CPtr = t.CVoid(base_ret_d - MEMBUDDY_HEADER_SIZE, t.CPtr) + dbg_hdr: t.CVoid | t.CPtr = t.CVoid(c.Deref(t.CUInt64T(dbg_block, t.CPtr)), t.CPtr) + dbg_order: t.CInt = t.CInt(t.CUInt64T(dbg_hdr) >> 1) + dbg_cur: t.CVoid | t.CPtr = t.CVoid(self.free_lists[dbg_order], t.CPtr) + dbg_n: t.CSizeT = 0 + while t.CUInt64T(dbg_cur) != 0: + if t.CUInt64T(dbg_cur) == t.CUInt64T(dbg_block): + stdio.printf("[MEMDBG] alloc 重复出块: size=%llu block=%llu 仍残留 free list order=%d(重复 put 实锤,终止)\n", + t.CUInt64T(size), t.CUInt64T(dbg_block), dbg_order) + stdio.fflush(None) stdlib.exit(1) - dup_i += 1 - if self._det_count >= self._det_cap: - # 记录表满:stdlib.realloc 翻倍扩容(防 is_alive/_det_probe - # 因容量耗尽漏检——SlotsBugTest 编译 includes 超 2M 次 alloc, - # 满后新块无记录 → is_alive 误报"读取悬空") - new_cap: t.CSizeT = self._det_cap * 2 - new_rec: t.CVoid | t.CPtr = t.CVoid( - stdlib.realloc(self._det_arena, new_cap * 16), t.CPtr) - if new_rec is not None: - self._det_arena = new_rec - self._det_records = (t.CUInt64T | t.CPtr)(t.CVoid(new_rec, t.CPtr)) - self._det_cap = new_cap - if self._det_count < self._det_cap: - self._det_records[self._det_count * 2] = base_ret_d + 2 - self._det_records[self._det_count * 2 + 1] = t.CUInt64T(size) - self._det_count += 1 - if (self._det_count & (MEMBUDDY_DET_PROBE_PERIOD - 1)) == 0: - self._det_probe() - result = t.CVoid(base_ret_d + 2, t.CPtr) + dbg_n += 1 + if dbg_n > self.usable_size / MEMBUDDY_MIN_BLOCK + 2: + stdio.printf("[MEMDBG] alloc 扫描 free list order=%d 成环/超长(自检异常,终止)\n", dbg_order) + stdio.fflush(None) + stdlib.exit(1) + dbg_cur = t.CVoid(c.Deref(t.CUInt64T(dbg_cur, t.CPtr)), t.CPtr) + if self._det_count >= self._det_cap: + # 记录表满:stdlib.realloc 翻倍扩容(防 is_alive/_det_probe + # 因容量耗尽漏检——SlotsBugTest 编译 includes 超 2M 次 alloc, + # 满后新块无记录 → is_alive 误报"读取悬空") + new_cap: t.CSizeT = self._det_cap * 2 + new_rec: t.CVoid | t.CPtr = t.CVoid( + stdlib.realloc(self._det_arena, new_cap * 16), t.CPtr) + if new_rec is not None: + self._det_arena = new_rec + self._det_records = (t.CUInt64T | t.CPtr)(t.CVoid(new_rec, t.CPtr)) + self._det_cap = new_cap + if self._det_count < self._det_cap: + self._det_records[self._det_count * 2] = rec_ptr_d + self._det_records[self._det_count * 2 + 1] = t.CUInt64T(size) + self._det_count += 1 + if self.detection != 0 and (self._det_count & (MEMBUDDY_DET_PROBE_PERIOD - 1)) == 0: + self._det_probe() + if self.detection != 0: + result = t.CVoid(base_ret_d + 2, t.CPtr) if result is None: # 分配失败诊断(定位"异常 size/池耗尽导致 None → 调用方解引用段错误") if size != 0 and self.usable is not None: @@ -751,27 +790,60 @@ class MemBuddy(MemManager): if self.detection != 0: # [DET] 返回指针比实际用户区靠后 2 字节,回收时向前偏移 2 p_eff = t.CVoid(t.CUInt64T(ptr) - 2, t.CPtr) - # 从记录表取本条真实 size,free 后把用户区填 0xCD(UAF 写入 - # 检测:free 后块被写穿 → 探测时 0xCD 被破坏 → 报警);记录 - # 保留并置 free 标志(探测时对仍 free 的块验证 0xCD 完整)。 - if self._det_records is not None: - ri: t.CSizeT = 0 - while ri < self._det_count: - rp: t.CUInt64T = self._det_records[ri * 2] - rs: t.CUInt64T = self._det_records[ri * 2 + 1] - if rp == t.CUInt64T(ptr) and (rs & (t.CUInt64T(1) << 63)) == 0: - if rs > 0: - string.memset(ptr, MEMBUDDY_FILL_PATTERN, rs) - self._det_records[ri * 2 + 1] = rs | (t.CUInt64T(1) << 63) - break - ri += 1 + # 记录表置 free 标志(解耦于 detection,2026-09-04):非 detection + # 也需置位,否则 free 后同地址再 alloc(正常 reuse)被误报重叠。 + if self._det_records is not None: + # 从记录表取本条真实 size(detection 下 free 后填 0xCD,UAF + # 写入检测:free 后块被写穿 → 探测时 0xCD 被破坏 → 报警); + # 记录保留并置 free 标志(探测时对仍 free 的块验证 0xCD 完整)。 + ri: t.CSizeT = 0 + while ri < self._det_count: + rp: t.CUInt64T = self._det_records[ri * 2] + rs: t.CUInt64T = self._det_records[ri * 2 + 1] + if rp == t.CUInt64T(ptr) and (rs & (t.CUInt64T(1) << 63)) == 0: + if self.detection != 0 and rs > 0: + string.memset(ptr, MEMBUDDY_FILL_PATTERN, rs) + self._det_records[ri * 2 + 1] = rs | (t.CUInt64T(1) << 63) + break + ri += 1 if self._is_valid_ptr(p_eff) != 0: block: t.CVoid | t.CPtr = t.CVoid(t.CUInt64T(p_eff) - MEMBUDDY_HEADER_SIZE, t.CPtr) stored: t.CVoid | t.CPtr = t.CVoid(c.Deref(t.CUInt64T(block, t.CPtr)), t.CPtr) stored_val: t.CUInt64T = t.CUInt64T(stored) order: t.CInt = t.CInt(stored_val >> 1) + if MEMBUDDY_DBG != 0: + # [MEMDBG] 重复归还检测:活跃块(header 奇数)绝不该已在本 order + # free list;命中 = 同块被 put 两次(free list 重复 put 实锤)。 + dbg_f: t.CVoid | t.CPtr = t.CVoid(self.free_lists[order], t.CPtr) + dbg_fn: t.CSizeT = 0 + while t.CUInt64T(dbg_f) != 0: + if t.CUInt64T(dbg_f) == t.CUInt64T(block): + stdio.printf("[MEMDBG] 重复归还: free(ptr=%llu) block=%llu 已在 free list order=%d(double-put 实锤,终止)\n", + t.CUInt64T(ptr), t.CUInt64T(block), order) + stdio.fflush(None) + stdlib.exit(1) + dbg_fn += 1 + if dbg_fn > self.usable_size / MEMBUDDY_MIN_BLOCK + 2: + stdio.printf("[MEMDBG] free 扫描 free list order=%d 成环/超长(自检异常,终止)\n", order) + stdio.fflush(None) + stdlib.exit(1) + dbg_f = t.CVoid(c.Deref(t.CUInt64T(dbg_f, t.CPtr)), t.CPtr) c.DerefAs(block, t.CVoid(0, t.CPtr)) self._coalesce(block, order) + elif MEMBUDDY_DBG != 0: + # [MEMDBG] 无效/悬空 free(原实现静默忽略):块在本池范围内但 header + # 为偶 = 已被释放/未初始化 → 悬空重复 free(stale 指针)。范围外 + # (非本池指针)是正常多池场景,不报。 + dbg_eff: t.CUInt64T = t.CUInt64T(p_eff) + dbg_blk: t.CUInt64T = dbg_eff - MEMBUDDY_HEADER_SIZE + if (dbg_eff >= MEMBUDDY_HEADER_SIZE and dbg_blk >= t.CUInt64T(self.usable) + and dbg_blk < t.CUInt64T(self.usable) + self.usable_size): + dbg_hv: t.CUInt64T = t.CUInt64T(t.CVoid(c.Deref(t.CUInt64T(t.CVoid(dbg_blk, t.CPtr), t.CPtr)), t.CPtr)) + if (dbg_hv & 1) == 0: + stdio.printf("[MEMDBG] 悬空/重复 free: ptr=%llu block=%llu header=0x%llX(偶数=已释放/未初始化,终止)\n", + t.CUInt64T(ptr), dbg_blk, dbg_hv) + stdio.fflush(None) + stdlib.exit(1) self._unlock() return 1 @@ -804,7 +876,8 @@ class MemBuddy(MemManager): self._rebuild_free_lists() # [DET] reset 重建全部 free list = 全部块释放:记录表同步清空, # 防止后续 alloc 复用旧块被误报(与 reset_to 截断同因)。 - if self.detection != 0 and self._det_records is not None: + # 2026-09-04 记录表已与 detection 解耦,清空条件同样不能挂 detection。 + if self._det_records is not None: self._det_count = 0 return 1 @@ -898,6 +971,7 @@ class MemBuddy(MemManager): if mfv_a != t.CUInt16T(MEMBUDDY_DET_MARKER): stdio.printf("[DET] 下溢写: ptr=%llu size=%llu 前标记=0x%04X(期望 0xCDCD)\n", p, s, t.CUInt32T(mfv_a)) + stdio.fflush(None) stdlib.exit(1) m16: t.CUInt16T | t.CPtr = (t.CUInt16T | t.CPtr)(t.CVoid(p + s, t.CPtr)) mv: t.CUInt16T = m16[0] @@ -938,6 +1012,7 @@ class MemBuddy(MemManager): stdio.printf("[%zu]sz=%llu ", ci3, cs3 & (free_flag - 1)) ci3 += 1 stdio.printf("\n") + stdio.fflush(None) stdlib.exit(1) i += 1 diff --git a/openssl/ssl.vp b/openssl/ssl.vp index c917bf3..b0a80e6 100644 --- a/openssl/ssl.vp +++ b/openssl/ssl.vp @@ -164,9 +164,12 @@ extern def SSL_get_verify_mode(ssl: SslPtr) -> int extern def SSL_get_peer_certificate(s: SslPtr) -> X509Ptr extern def SSL_get1_peer_certificate(s: SslPtr) -> X509Ptr # 当前加密套件 -# const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) → 文本用下句 -# const char *SSL_get_cipher_name(const SSL *s) / int SSL_get_cipher_bits -extern def SSL_get_cipher_name(s: SslPtr) -> str +# SSL_get_cipher_name 在 ssl.h 是宏(SSL_CIPHER_get_name(SSL_get_current_cipher(s))), +# FFI 拆成两个真实导出函数调用: +# const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) +extern def SSL_get_current_cipher(s: SslPtr) -> SslCipherPtr +# const char *SSL_CIPHER_get_name(const SSL_CIPHER *c) +extern def SSL_CIPHER_get_name(cipher: SslCipherPtr) -> str # SNI: int SSL_set_tlsext_host_name(SSL *s, const char *name)(宏 → SSL_ctrl) # const char *SSL_get_servername(const SSL *s, int type) extern def SSL_get_servername(s: SslPtr, type: int) -> str diff --git a/openssl/types.vp b/openssl/types.vp index 54b1816..5675aa9 100644 --- a/openssl/types.vp +++ b/openssl/types.vp @@ -4,61 +4,66 @@ import t, c # openssl/types.vp — OpenSSL 3.x 不透明对象句柄 typedef # # 对接 libcrypto / libssl(OpenSSL 3.x 导出符号)。 -# 对象一律按不透明指针 (i8*) 处理,生命周期由 OpenSSL 库管理 +# 对象一律按不透明指针 (void*) 处理,生命周期由 OpenSSL 库管理 # (X509_free/SSL_free/BIO_free/CRYPTO_free 等对应释放函数)。 -# 链接目标:ViperOpenSSLProject 的 project.vpj 后续配置 -# (msys2 mingw64 libcrypto/libssl 或 openssl_358_C 自编译库)。 +# 链接目标:ViperOpenSSLProject 的 project.vpj 链接 openssl_358_C +# 自编译静态库(libcrypto.a / libssl.a)。 +# +# 注意:typedef 用 `t.CVoid | t.CPtr` 表达(与 vqt6 一致),生成 i8* +# 指针参数,可被 ASan 插桩;纯 `t.CPtr` 会生成 opaque struct 参数, +# opt -passes=asan 会报 invalid type for function argument。 # ============================================================ # ---- 基础上下文 ---- -OsslLibCtxPtr: t.CTypedef = t.CPtr # OSSL_LIB_CTX* -EnginePtr: t.CTypedef = t.CPtr # ENGINE* -OpensslInitSettingsPtr: t.CTypedef = t.CPtr # OPENSSL_INIT_SETTINGS* +OsslLibCtxPtr: t.CTypedef = t.CVoid | t.CPtr # OSSL_LIB_CTX* +EnginePtr: t.CTypedef = t.CVoid | t.CPtr # ENGINE* +OpensslInitSettingsPtr: t.CTypedef = t.CVoid | t.CPtr # OPENSSL_INIT_SETTINGS* # ---- BIO(内存/文件/Socket/Connect)---- -BioPtr: t.CTypedef = t.CPtr # BIO* -BioMethodPtr: t.CTypedef = t.CPtr # BIO_METHOD* -BioAddrPtr: t.CTypedef = t.CPtr # BIO_ADDR* -BioAddrInfoPtr: t.CTypedef = t.CPtr # BIO_ADDRINFO* +BioPtr: t.CTypedef = t.CVoid | t.CPtr # BIO* +BioMethodPtr: t.CTypedef = t.CVoid | t.CPtr # BIO_METHOD* +BioAddrPtr: t.CTypedef = t.CVoid | t.CPtr # BIO_ADDR* +BioAddrInfoPtr: t.CTypedef = t.CVoid | t.CPtr # BIO_ADDRINFO* # ---- EVP(摘要/对称/非对称)---- -EvpMdPtr: t.CTypedef = t.CPtr # EVP_MD* -EvpMdCtxPtr: t.CTypedef = t.CPtr # EVP_MD_CTX* -EvpCipherPtr: t.CTypedef = t.CPtr # EVP_CIPHER* -EvpCipherCtxPtr: t.CTypedef = t.CPtr # EVP_CIPHER_CTX* -EvpPkeyPtr: t.CTypedef = t.CPtr # EVP_PKEY* -EvpPkeyCtxPtr: t.CTypedef = t.CPtr # EVP_PKEY_CTX* -EvpEncodeCtxPtr: t.CTypedef = t.CPtr # EVP_ENCODE_CTX* -HmacCtxPtr: t.CTypedef = t.CPtr # HMAC_CTX* +EvpMdPtr: t.CTypedef = t.CVoid | t.CPtr # EVP_MD* +EvpMdCtxPtr: t.CTypedef = t.CVoid | t.CPtr # EVP_MD_CTX* +EvpCipherPtr: t.CTypedef = t.CVoid | t.CPtr # EVP_CIPHER* +EvpCipherCtxPtr: t.CTypedef = t.CVoid | t.CPtr # EVP_CIPHER_CTX* +EvpPkeyPtr: t.CTypedef = t.CVoid | t.CPtr # EVP_PKEY* +EvpPkeyCtxPtr: t.CTypedef = t.CVoid | t.CPtr # EVP_PKEY_CTX* +EvpEncodeCtxPtr: t.CTypedef = t.CVoid | t.CPtr # EVP_ENCODE_CTX* +HmacCtxPtr: t.CTypedef = t.CVoid | t.CPtr # HMAC_CTX* # ---- X509 / 证书 ---- -X509Ptr: t.CTypedef = t.CPtr # X509* -X509NamePtr: t.CTypedef = t.CPtr # X509_NAME* -X509NameEntryPtr: t.CTypedef = t.CPtr # X509_NAME_ENTRY* -X509CrlPtr: t.CTypedef = t.CPtr # X509_CRL* -X509ReqPtr: t.CTypedef = t.CPtr # X509_REQ* -X509ExtensionPtr: t.CTypedef = t.CPtr # X509_EXTENSION* -X509StorePtr: t.CTypedef = t.CPtr # X509_STORE* -X509StoreCtxPtr: t.CTypedef = t.CPtr # X509_STORE_CTX* -X509InfoPtr: t.CTypedef = t.CPtr # X509_INFO* -X509VerifyParamPtr: t.CTypedef = t.CPtr # X509_VERIFY_PARAM* +X509Ptr: t.CTypedef = t.CVoid | t.CPtr # X509* +X509NamePtr: t.CTypedef = t.CVoid | t.CPtr # X509_NAME* +X509NameEntryPtr: t.CTypedef = t.CVoid | t.CPtr # X509_NAME_ENTRY* +X509CrlPtr: t.CTypedef = t.CVoid | t.CPtr # X509_CRL* +X509ReqPtr: t.CTypedef = t.CVoid | t.CPtr # X509_REQ* +X509ExtensionPtr: t.CTypedef = t.CVoid | t.CPtr # X509_EXTENSION* +X509StorePtr: t.CTypedef = t.CVoid | t.CPtr # X509_STORE* +X509StoreCtxPtr: t.CTypedef = t.CVoid | t.CPtr # X509_STORE_CTX* +X509InfoPtr: t.CTypedef = t.CVoid | t.CPtr # X509_INFO* +X509VerifyParamPtr: t.CTypedef = t.CVoid | t.CPtr # X509_VERIFY_PARAM* # ---- ASN.1 ---- -Asn1ObjectPtr: t.CTypedef = t.CPtr # ASN1_OBJECT* -Asn1StringPtr: t.CTypedef = t.CPtr # ASN1_STRING* -Asn1IntegerPtr: t.CTypedef = t.CPtr # ASN1_INTEGER* -Asn1TimePtr: t.CTypedef = t.CPtr # ASN1_TIME* -Asn1OctetStringPtr: t.CTypedef = t.CPtr # ASN1_OCTET_STRING* -Asn1BitStringPtr: t.CTypedef = t.CPtr # ASN1_BIT_STRING* -GeneralNamesPtr: t.CTypedef = t.CPtr # GENERAL_NAMES* -GeneralNamePtr: t.CTypedef = t.CPtr # GENERAL_NAME* +Asn1ObjectPtr: t.CTypedef = t.CVoid | t.CPtr # ASN1_OBJECT* +Asn1StringPtr: t.CTypedef = t.CVoid | t.CPtr # ASN1_STRING* +Asn1IntegerPtr: t.CTypedef = t.CVoid | t.CPtr # ASN1_INTEGER* +Asn1TimePtr: t.CTypedef = t.CVoid | t.CPtr # ASN1_TIME* +Asn1OctetStringPtr: t.CTypedef = t.CVoid | t.CPtr # ASN1_OCTET_STRING* +Asn1BitStringPtr: t.CTypedef = t.CVoid | t.CPtr # ASN1_BIT_STRING* +GeneralNamesPtr: t.CTypedef = t.CVoid | t.CPtr # GENERAL_NAMES* +GeneralNamePtr: t.CTypedef = t.CVoid | t.CPtr # GENERAL_NAME* # ---- SSL/TLS ---- -SslPtr: t.CTypedef = t.CPtr # SSL* -SslCtxPtr: t.CTypedef = t.CPtr # SSL_CTX* -SslMethodPtr: t.CTypedef = t.CPtr # SSL_METHOD* -SslSessionPtr: t.CTypedef = t.CPtr # SSL_SESSION* +SslPtr: t.CTypedef = t.CVoid | t.CPtr # SSL* +SslCtxPtr: t.CTypedef = t.CVoid | t.CPtr # SSL_CTX* +SslMethodPtr: t.CTypedef = t.CVoid | t.CPtr # SSL_METHOD* +SslSessionPtr: t.CTypedef = t.CVoid | t.CPtr # SSL_SESSION* +SslCipherPtr: t.CTypedef = t.CVoid | t.CPtr # SSL_CIPHER* # ---- BIGNUM ---- -BnPtr: t.CTypedef = t.CPtr # BIGNUM* -BnCtxPtr: t.CTypedef = t.CPtr # BN_CTX* +BnPtr: t.CTypedef = t.CVoid | t.CPtr # BIGNUM* +BnCtxPtr: t.CTypedef = t.CVoid | t.CPtr # BN_CTX* diff --git a/os/path.vp b/os/path.vp index af38b91..ef6be80 100644 --- a/os/path.vp +++ b/os/path.vp @@ -226,7 +226,7 @@ def normpath(path: str) -> str: out_pos: t.CSizeT = 0 i: t.CSizeT = 0 - s: str = sep() + s: t.CChar = sep() # 处理绝对路径前缀 is_absolute: bool = False diff --git a/posix.vp b/posix.vp index 3a0d7b5..7d588eb 100644 --- a/posix.vp +++ b/posix.vp @@ -215,7 +215,7 @@ extern def isatty(fd: INT) -> INT # ============================================================================= -# Inline macros (C macros, implemented as normal functions, not marked as t.CExtern) +# Inline macros (C macros, implemented as normal functions, not marked as extern) # ============================================================================= # st_mode type determination diff --git a/socket.vp b/socket.vp index 163873e..7a8e2d3 100644 --- a/socket.vp +++ b/socket.vp @@ -82,19 +82,18 @@ class timeval: # (Windows SOCKET=u64, POSIX fd=int → u64 Zero-Extension Compatible) # ============================================================ -def socket(family: INT, type: INT, protocol: INT) -> u64 | t.CExtern | t.CExport: pass -def connect(fd: u64, addr: SocketAddr | t.CPtr, addrlen: INT) -> INT | t.CExtern | t.CExport: pass -def send(fd: u64, buf: t.CVoid | t.CPtr, len: INT, flags: INT) -> INT | t.CExtern | t.CExport: pass -def recv(fd: u64, buf: t.CVoid | t.CPtr, len: INT, flags: INT) -> INT | t.CExtern | t.CExport: pass -def bind(fd: u64, addr: SocketAddr | t.CPtr, addrlen: INT) -> INT | t.CExtern | t.CExport: pass -def listen(fd: u64, backlog: INT) -> INT | t.CExtern | t.CExport: pass -def accept(fd: u64, addr: SocketAddr | t.CPtr, addrlen: INT | t.CPtr) -> u64 | t.CExtern | t.CExport: pass -def setsockopt(fd: u64, level: INT, optname: INT, optval: t.CVoid | t.CPtr, optlen: INT) -> INT | t.CExtern | t.CExport: pass -def gethostbyname(name: t.CChar | t.CConst | t.CPtr) -> HostEnt | t.CPtr | t.CExtern | t.CExport: pass -def ntohs(netshort: u16) -> u16 | t.CExtern | t.CExport: pass -def htons(hostshort: u16) -> u16 | t.CExtern | t.CExport: pass -def close(fd: u64) -> INT | t.CExtern | t.CExport: pass - +extern def socket(family: INT, type: INT, protocol: INT) -> u64 +extern def connect(fd: u64, addr: SocketAddr | t.CPtr, addrlen: INT) -> INT +extern def send(fd: u64, buf: t.CVoid | t.CPtr, len: INT, flags: INT) -> INT +extern def recv(fd: u64, buf: t.CVoid | t.CPtr, len: INT, flags: INT) -> INT +extern def bind(fd: u64, addr: SocketAddr | t.CPtr, addrlen: INT) -> INT +extern def listen(fd: u64, backlog: INT) -> INT +extern def accept(fd: u64, addr: SocketAddr | t.CPtr, addrlen: INT | t.CPtr) -> u64 +extern def setsockopt(fd: u64, level: INT, optname: INT, optval: t.CVoid | t.CPtr, optlen: INT) -> INT +extern def gethostbyname(name: t.CConst | str) -> HostEnt | t.CPtr +extern def ntohs(netshort: u16) -> u16 +extern def htons(hostshort: u16) -> u16 +extern def close(fd: u64) -> INT # ============================================================ # Internal Auxiliary Functions diff --git a/string.vp b/string.vp index fdaa966..7926dbb 100644 --- a/string.vp +++ b/string.vp @@ -66,20 +66,23 @@ def strncat(dest: str, src: str, n: t.CSizeT) -> str: # String length function -def strlen(src: str) -> t.CSizeT | t.CExport: +export def strlen(src: str) -> t.CSizeT: length: t.CSizeT = 0 for _ in src: length += 1 return length # String comparison function +# 注意:str1[0] - str2[0] 是 i8 减法会回绕(0xFF 表示 -1),返回前必须 +# int() 提升到 i32 再相减(与下方 memcmp 的 int(p1[i]) - int(p2[i]) 一致), +# 否则 strcmp("abc","abd") 返回 255 而非 -1(StringTest Test 4 根因)。 def strcmp(str1: str, str2: str) -> int: while str1[0] != '\0' and str2[0] != '\0': if str1[0] != str2[0]: - return str1[0] - str2[0] + return int(str1[0]) - int(str2[0]) str1 += 1 str2 += 1 - return str1[0] - str2[0] + return int(str1[0]) - int(str2[0]) def samestr(str1: str, str2: str) -> bool: return strcmp(str1, str2) == 0 @@ -90,12 +93,12 @@ def strncmp(str1: str, str2: str, n: t.CSizeT) -> int: i: t.CSizeT = 0 while str1[0] != '\0' and str2[0] != '\0' and i < n: if str1[0] != str2[0]: - return str1[0] - str2[0] + return int(str1[0]) - int(str2[0]) str1 += 1 str2 += 1 i += 1 if i < n: - return str1[0] - str2[0] + return int(str1[0]) - int(str2[0]) return 0 @@ -164,7 +167,7 @@ def strspn(s: str, skip: str = " ") -> int: return si # Memory set function -def memset(ptr: t.CVoid | t.CPtr, value: int, num: t.CSizeT) -> t.CVoid | t.CPtr | t.CExport: +export def memset(ptr: t.CVoid | t.CPtr, value: int, num: t.CSizeT) -> t.CVoid | t.CPtr: # Original implementation: # p: BYTEPTR = BYTEPTR(ptr) # i: t.CSizeT @@ -197,7 +200,7 @@ def memset32(ptr: t.CVoid | t.CPtr, value: t.CUInt32T, count: t.CSizeT) -> t.CVo # Memory copy function -def memcpy(dest: t.CVoid | t.CPtr, src: t.CVoid | t.CPtr, num: t.CSizeT) -> t.CVoid | t.CPtr | t.CExport: +export def memcpy(dest: t.CVoid | t.CPtr, src: t.CVoid | t.CPtr, num: t.CSizeT) -> t.CPtr: # Original implementation: # d: BYTEPTR = BYTEPTR(dest) # s: BYTEPTR = BYTEPTR(src) diff --git a/viperlib.vp b/viperlib.vp index f0cecb6..f175e84 100644 --- a/viperlib.vp +++ b/viperlib.vp @@ -12,7 +12,7 @@ def get_digit_count(num: t.CUnsignedInt, base: t.CInt) -> t.CStatic | t.CInt: num //= base return count -def sprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CVoid | t.CExport: +export def sprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CVoid: if buf is None or rule is None: return vsnprintf(buf, 0x7FFFFFFF, rule, args) @@ -20,33 +20,33 @@ def vsprintf(buf: t.CChar | t.CPtr, rule: str, *args) -> t.CInt: if buf is None or rule is None: return 0 return vsnprintf(buf, 0x7FFFFFFF, rule, args) -def snprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, *args) -> t.CInt | t.CExport: +export def snprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, *args) -> t.CInt: if fmt is None: return 0 if buf is None or size == 0: return vsnprintf(None, 0, fmt, args) - ret: t.CInt = vsnprintf(buf, size, fmt, args) + ret: int = vsnprintf(buf, size, fmt, args) return ret # Check floating-point special values (IEEE 754) # Return: 0=normal, 1=+inf, 2=-inf, 3=nan -def _check_special_float(fv: t.CDouble) -> t.CInt: +def _check_special_float(fv: double) -> int: fbits: t.CUInt64T = 0 c.Load(c.Addr(fbits), c.Addr(fv)) if ((fbits >> 52) & 0x7FF) != 0x7FF: return 0 - is_neg: t.CInt = 1 if (fbits >> 63) != 0 else 0 + is_neg: int = 1 if (fbits >> 63) != 0 else 0 if (fbits & 0x000FFFFFFFFFFFFF) == 0: if is_neg: return 2 return 1 return 3 -def vsnprintf(buf: t.CChar | t.CPtr, size: t.CSizeT, fmt: str, ap: t.CChar | t.CPtr) -> t.CInt | t.CExport: +export def vsnprintf(buf: bytes, size: t.CSizeT, fmt: str, ap: t.CChar | t.CPtr) -> int: if fmt is None: return 0 # 长度探测模式:buf is None 时只计算格式化后长度,不实际写入 # _step=0 使 ptr 不前进,反复写入同一个 dummy 字节(无害),write_count 正确累加 - count_mode: t.CInt = 0 - _step: t.CInt = 1 + count_mode: int = 0 + _step: int = 1 _dummy: t.CChar = '\0' if buf is None or size == 0: count_mode = 1 diff --git a/vqt6/_bridge_widgets.cpp b/vqt6/_bridge_widgets.cpp index 636440a..5885e58 100644 --- a/vqt6/_bridge_widgets.cpp +++ b/vqt6/_bridge_widgets.cpp @@ -19,8 +19,13 @@ #include #include #include +#include +#include +#include +#include #include #include +#include #include #include #include @@ -853,6 +858,70 @@ extern "C" VQT6_API int vqt6_qplaintextedit_line_count(void* pte) { // QCheckBox / QRadioButton // ============================================================ +// ------------------------------------------------------------------ +// 共享的“勾选指示器”渲染(自绘 QCheckBox 与树形勾选代理复用同一套绘制) +// ------------------------------------------------------------------ +static QColor vqt6_mix_color(const QColor& a, const QColor& b, qreal t) { + if (t < 0.0) t = 0.0; + else if (t > 1.0) t = 1.0; + return QColor::fromRgbF(a.redF() + (b.redF() - a.redF()) * t, + a.greenF() + (b.greenF() - a.greenF()) * t, + a.blueF() + (b.blueF() - a.blueF()) * t, + a.alphaF() + (b.alphaF() - a.alphaF()) * t); +} + +// 规整指示区:内部收缩 1px;过小时回退为 16×16 并居中 +static QRectF vqt6_indicator_box(const QRect& r) { + QRectF box(r.left() + 1.0, r.top() + 1.0, r.width() - 2.0, r.height() - 2.0); + if (box.width() < 10.0 || box.height() < 10.0) { + box = QRectF(0, 0, 16, 16); + box.moveCenter(QRectF(r).center()); + } + return box; +} + +// 统一的指示器绘制:圆角框 + QPalette 配色 + 对勾(或半选横线) +// box —— 绘制区域(约 16~18px 见方) +// pal —— 控件调色板(决定深浅主题配色) +// enabled —— 是否可用 +// progress —— 勾选过渡进度(0=未选 1=选中) +// partial —— 半选态(画横线,progress 按 1 传入) +static void vqt6_paint_check_indicator(QPainter* p, const QRectF& box, const QPalette& pal, + bool enabled, qreal progress, bool partial) { + p->setRenderHint(QPainter::Antialiasing, true); + const qreal t = progress < 0.0 ? 0.0 : (progress > 1.0 ? 1.0 : progress); + const QColor cBase = enabled ? pal.base().color() : pal.window().color(); + const QColor cOn = enabled ? pal.highlight().color() : pal.button().color(); + const QColor cB0 = enabled ? pal.text().color() : pal.placeholderText().color(); + const QColor cB1 = enabled ? pal.highlight().color() : pal.buttonText().color(); + const QColor fill = vqt6_mix_color(cBase, cOn, t); + const QColor border = vqt6_mix_color(cB0, cB1, t); + + QPainterPath path; + path.addRoundedRect(box, 3.0, 3.0); + p->fillPath(path, fill); + QPen bpen(border, 1.4); + p->setPen(bpen); + p->drawPath(path); + + if (!enabled || t <= 0.003) return; + QColor gc = pal.highlightedText().color(); + gc.setAlphaF(gc.alphaF() * t); + const qreal x0 = box.left(), y0 = box.top(), w = box.width(), h = box.height(); + if (partial) { + QPen dpen(gc, 1.6); + dpen.setCapStyle(Qt::RoundCap); + p->setPen(dpen); + p->drawLine(QPointF(x0 + w * 0.22, y0 + h * 0.5), QPointF(x0 + w * 0.78, y0 + h * 0.5)); + } else { + QPen cpen(gc, 1.6 + 0.8 * t); + cpen.setCapStyle(Qt::RoundCap); + p->setPen(cpen); + p->drawLine(QPointF(x0 + w * 0.24, y0 + h * 0.54), QPointF(x0 + w * 0.43, y0 + h * 0.73)); + p->drawLine(QPointF(x0 + w * 0.43, y0 + h * 0.73), QPointF(x0 + w * 0.78, y0 + h * 0.28)); + } +} + // 自绘 QCheckBox:矢量框+对勾按 QPalette 绘制,勾选带过渡动画 class vqt6_CheckBox : public QCheckBox { public: @@ -875,41 +944,12 @@ protected: r = QRect(0, 0, 16, 16); r.moveCenter(QPoint(rect().left() + 12, rect().center().y())); } - QRectF box(r.left() + 1.0, r.top() + 1.0, r.width() - 2.0, r.height() - 2.0); - if (box.width() < 10.0 || box.height() < 10.0) { - box = QRectF(0, 0, 16, 16); - box.moveCenter(QPointF(r.center().x(), r.center().y())); - } - const bool en = isEnabled(); - qreal t = m_progress; - if (t < 0.0) t = 0.0; - else if (t > 1.0) t = 1.0; - QColor cBase = en ? pal.base().color() : pal.window().color(); - QColor cOn = en ? pal.highlight().color() : pal.button().color(); - QColor cBorder0 = en ? pal.text().color() : pal.placeholderText().color(); - QColor cBorder1 = en ? pal.highlight().color() : pal.buttonText().color(); - QColor fill = mix(cBase, cOn, t); - QColor border = mix(cBorder0, cBorder1, t); - QPainterPath path; - path.addRoundedRect(box, 3.0, 3.0); - p.fillPath(path, fill); - QPen bpen(border, 1.4); - p.setPen(bpen); - p.drawPath(path); - if (en && t > 0.003) { - QColor gc = pal.highlightedText().color(); - gc.setAlphaF(gc.alphaF() * t); - QPen cpen(gc, 1.6 + 0.8 * t); - cpen.setCapStyle(Qt::RoundCap); - p.setPen(cpen); - const qreal x0 = box.left(), y0 = box.top(), w = box.width(), h = box.height(); - p.drawLine(QPointF(x0 + w * 0.24, y0 + h * 0.54), QPointF(x0 + w * 0.43, y0 + h * 0.73)); - p.drawLine(QPointF(x0 + w * 0.43, y0 + h * 0.73), QPointF(x0 + w * 0.78, y0 + h * 0.28)); - } + // 框 + 对勾:与树形勾选共用同一渲染(含动画进度) + vqt6_paint_check_indicator(&p, vqt6_indicator_box(r), pal, isEnabled(), m_progress, false); // 文本 QRect lr = style()->subElementRect(QStyle::SE_CheckBoxContents, &opt, this); if (!lr.isEmpty() && !lr.isNull()) { - p.setPen(QPen(en ? pal.text() : pal.placeholderText(), 1.0)); + p.setPen(QPen(isEnabled() ? pal.text() : pal.placeholderText(), 1.0)); p.drawText(lr, Qt::AlignLeft | Qt::AlignVCenter, text()); } } @@ -949,13 +989,6 @@ private: m_progress = m_target; m_timer.stop(); } - - static QColor mix(const QColor& a, const QColor& b, qreal t) { - return QColor::fromRgbF(a.redF() + (b.redF() - a.redF()) * t, - a.greenF() + (b.greenF() - a.greenF()) * t, - a.blueF() + (b.blueF() - a.blueF()) * t, - a.alphaF() + (b.alphaF() - a.alphaF()) * t); - } }; extern "C" VQT6_API void* vqt6_qcheckbox_create(void) { @@ -1002,6 +1035,136 @@ extern "C" VQT6_API int vqt6_qcheckbox_is_tristate(void* cb) { return static_cast(cb)->isTristate() ? 1 : 0; } +// ============================================================ +// item-view(QTreeWidget 等)勾选框自绘代理 +// 拦截 PE_IndicatorItemViewItemCheck,复用 vqt6_paint_check_indicator, +// 与自绘 QCheckBox 观感一致(含勾选过渡动画:QTreeWidget 勾选变化时 +// 按 60fps 指数衰减驱动对应 item 重绘,动画节奏与复选框完全相同)。 +// 采用 QProxyStyle 默认构造(基样式按需自动创建),应用 setStyle 后由 +// Qt 管理生命周期 —— 与 Qt 官方 QProxyStyle 示例一致,避免基样式 +// 所有权/悬空问题。 +// ============================================================ +class vqt6_CheckProxyStyle : public QProxyStyle { +public: + vqt6_CheckProxyStyle() : QProxyStyle() { + m_timer.setInterval(16); + QObject::connect(&m_timer, &QTimer::timeout, this, [this]() { advance(); }); + } + + void drawPrimitive(PrimitiveElement element, const QStyleOption* option, + QPainter* painter, const QWidget* widget) const override { + if (element == PE_IndicatorItemViewItemCheck && option != nullptr && painter != nullptr) { + drawItemCheck(option, painter, widget); + return; + } + QProxyStyle::drawPrimitive(element, option, painter, widget); + } + +private: + struct AnimState { + qreal progress = 0.0; // 当前绘制进度 0..1 + qreal target = 0.0; // 目标进度 + }; + + // 勾选动画记录(键 = QTreeWidgetItem* 指针值) + mutable QHash m_anims; + // 已绑定 itemChanged 的树视图(避免重复连接) + mutable QSet m_hooked; + // 动画期间需要定时重绘的树视图 + mutable QSet m_repaint; + mutable QTimer m_timer; + + void drawItemCheck(const QStyleOption* option, QPainter* painter, const QWidget* widget) const { + const bool enabled = (option->state & QStyle::State_Enabled) != 0; + const bool on = (option->state & QStyle::State_On) != 0; + const bool partial = (option->state & QStyle::State_NoChange) != 0; + qreal progress = (on || partial) ? 1.0 : 0.0; + + // 懒绑定 QTreeWidget:勾选变化时驱动对应 item 的过渡动画 + QTreeWidget* tw = (widget != nullptr) + ? const_cast(qobject_cast(widget)) : nullptr; + if (tw != nullptr) { + if (!m_hooked.contains(tw)) { + m_hooked.insert(tw); + QObject::connect(tw, &QTreeWidget::itemChanged, this, + [this, tw](QTreeWidgetItem* item, int) { onItemChanged(tw, item); }); + } + const QStyleOptionViewItem* vopt = qstyleoption_cast(option); + if (vopt != nullptr && vopt->index.isValid()) { + const quintptr key = quintptr(vopt->index.internalPointer()); + auto it = m_anims.constFind(key); + if (it != m_anims.constEnd()) + progress = it->progress; + } + } + + const QPalette& pal = (widget != nullptr) ? widget->palette() + : QApplication::palette(); + vqt6_paint_check_indicator(painter, vqt6_indicator_box(option->rect), + pal, enabled, progress, partial); + } + + void onItemChanged(QTreeWidget* tw, QTreeWidgetItem* item) const { + if (tw == nullptr || item == nullptr) return; + const Qt::CheckState cs = item->checkState(0); + const bool on = (cs == Qt::Checked || cs == Qt::PartiallyChecked); + const qreal target = on ? 1.0 : 0.0; + const quintptr key = quintptr(static_cast(item)); + auto it = m_anims.find(key); + if (it == m_anims.end()) { + // 从“变化前”的观感出发开始过渡(与复选框一致:勾选=淡入对勾, + // 取消勾选=淡出),中途连续切换时延续当前进度。 + AnimState st; + st.progress = (target > 0.5) ? 0.0 : 1.0; + st.target = target; + m_anims.insert(key, st); + } else { + it->target = target; + } + if (!tw->isVisible()) { + // 建页/初始化阶段的程序化勾选:直接落定,不产生无谓动画 + m_anims.remove(key); + return; + } + m_repaint.insert(tw); + tw->viewport()->update(); + if (!m_timer.isActive()) + m_timer.start(); + } + + void advance() const { + QList done; + for (auto it = m_anims.begin(); it != m_anims.end(); ++it) { + AnimState& st = it.value(); + st.progress += (st.target - st.progress) * 0.25; + if (qAbs(st.target - st.progress) < 0.005) { + st.progress = st.target; + done.append(it.key()); + } + } + for (quintptr k : done) + m_anims.remove(k); + for (QTreeWidget* tw : m_repaint) { + if (tw != nullptr && tw->viewport() != nullptr) + tw->viewport()->update(); + } + if (m_anims.isEmpty()) { + m_repaint.clear(); + m_timer.stop(); + } + } +}; + +extern "C" VQT6_API void vqt6_enable_custom_item_checks(void* app) { + QApplication* a = (app != nullptr) ? static_cast(app) + : static_cast(QApplication::instance()); + if (a == nullptr) return; + static bool s_custom_checks_enabled = false; + if (s_custom_checks_enabled) return; // 幂等:只安装一次 + s_custom_checks_enabled = true; + a->setStyle(new vqt6_CheckProxyStyle()); +} + extern "C" VQT6_API void* vqt6_qradiobutton_create(void) { return new QRadioButton(); } diff --git a/vqt6/_bridge_widgets.h b/vqt6/_bridge_widgets.h index 188220c..cacebc0 100644 --- a/vqt6/_bridge_widgets.h +++ b/vqt6/_bridge_widgets.h @@ -25,6 +25,7 @@ VQT6_API int vqt6_qapplication_desktop_height(void* app); VQT6_API void vqt6_qapplication_set_quit_on_last_window_closed(void* app, int quit); VQT6_API int vqt6_qapplication_quit_on_last_window_closed(void* app); VQT6_API void vqt6_qapplication_set_theme_palette(void* app, int theme); +VQT6_API void vqt6_enable_custom_item_checks(void* app); // ============================================================ // QWidget diff --git a/vqt6/_qtwidgets.vp b/vqt6/_qtwidgets.vp index b91cc9b..574998f 100644 --- a/vqt6/_qtwidgets.vp +++ b/vqt6/_qtwidgets.vp @@ -21,6 +21,7 @@ def vqt6_qapplication_desktop_height(app: QtAppPtr) -> t.CInt | t.State: pass def vqt6_qapplication_set_quit_on_last_window_closed(app: QtAppPtr, quit: t.CInt) -> t.State: pass def vqt6_qapplication_quit_on_last_window_closed(app: QtAppPtr) -> t.CInt | t.State: pass def vqt6_qapplication_set_theme_palette(app: QtAppPtr, theme: t.CInt) -> t.State: pass +def vqt6_enable_custom_item_checks(app: QtAppPtr) -> t.State: pass # ============================================================ diff --git a/w32/fileio.vp b/w32/fileio.vp index 61b1ac9..759811f 100644 --- a/w32/fileio.vp +++ b/w32/fileio.vp @@ -129,7 +129,7 @@ class File: if self.closed: return FRESULT.ERR_CLOSED if not self.can_write: return FRESULT.ERR_PERM bytes_written: ULONG = 0 - result: BOOL = w32.win32file.WriteFile(self.handle, buf, count, t.CPtr(c.Addr(bytes_written)), None) + result: BOOL = w32.win32file.WriteFile(self.handle, buf, count, c.Addr(bytes_written), None) if result == 0: return FRESULT.ERR_IO return LONG(bytes_written) diff --git a/zipfile.vp b/zipfile.vp index d9a7e2d..560ac6a 100644 --- a/zipfile.vp +++ b/zipfile.vp @@ -24,7 +24,9 @@ import t, c from stdint import * import stdlib import string -import w32.fileio as fio +import viperlib +import w32.win32base as wb +import w32.win32file as wf import zlib.pyzlib as zpy @@ -71,6 +73,16 @@ def zipfile_set_error(code: t.CInt, msg: str): zipfile_error_msg[0] = '\0' +def zipfile_set_error_win(code: t.CInt, msg: str, err: ULONG): + global zipfile_error_code_val, zipfile_error_msg + zipfile_error_code_val = code + if err != 0: + viperlib.snprintf(zipfile_error_msg, 256, "%s (win32 err=%u)", msg, err) + else: + string.strncpy(zipfile_error_msg, msg, 255) + zipfile_error_msg[255] = '\0' + + def error_code() -> t.CInt: return zipfile_error_code_val @@ -124,31 +136,47 @@ def zf_w32le(h: BYTEPTR, v: t.CUInt32T): h[3] = (v >> 24) & 0xFF -def zf_fwrite_all(f: fio.File | t.CPtr, p: BYTEPTR, n: t.CSizeT) -> t.CInt: +# 所有文件打开都允许读/写/删共享,避免句柄互斥 +_ZF_SHARE: t.CDefine = 7 # FILE_SHARE_READ|WRITE|DELETE + + +def zf_share_flags() -> ULONG: + return ULONG(_ZF_SHARE) + + +def zf_write_all(h: wb.HANDLE, p: BYTEPTR, n: t.CSizeT) -> t.CInt: done: t.CSizeT = 0 while done < n: chunk: t.CSizeT = n - done if chunk > 0xFFFFFF00: chunk = 0xFFFFFF00 - w: LONG = f.write(p + done, ULONG(chunk)) - if w <= 0: - zipfile_set_error(ZIP_ERR_IO, "write failed") + written: ULONG = 0 + ok: BOOL = wf.WriteFile(h, p + done, ULONG(chunk), c.Addr(written), None) + if ok == 0 or written == 0: + global zipfile_error_code_val, zipfile_error_msg + zipfile_error_code_val = ZIP_ERR_IO + viperlib.snprintf(zipfile_error_msg, 256, + "write failed (win32_err=%u)", wb.GetLastError()) return ZIP_ERR_IO - done += t.CSizeT(w) + done += t.CSizeT(written) return ZIP_ERR_OK -def zf_fread_all(f: fio.File | t.CPtr, p: BYTEPTR, n: t.CSizeT) -> t.CInt: +def zf_read_all(h: wb.HANDLE, p: BYTEPTR, n: t.CSizeT) -> t.CInt: done: t.CSizeT = 0 while done < n: chunk: t.CSizeT = n - done if chunk > 0xFFFFFF00: chunk = 0xFFFFFF00 - rd: LONG = f.read(p + done, ULONG(chunk)) - if rd <= 0: - zipfile_set_error(ZIP_ERR_IO, "read failed") + bytes_read: ULONG = 0 + ok: BOOL = wf.ReadFile(h, p + done, ULONG(chunk), c.Addr(bytes_read), None) + if ok == 0 or bytes_read == 0: + global zipfile_error_code_val, zipfile_error_msg + zipfile_error_code_val = ZIP_ERR_IO + viperlib.snprintf(zipfile_error_msg, 256, + "read failed (win32_err=%u)", wb.GetLastError()) return ZIP_ERR_IO - done += t.CSizeT(rd) + done += t.CSizeT(bytes_read) return ZIP_ERR_OK @@ -156,27 +184,30 @@ def zf_read_whole(path: str, out_len: t.CSizeT | t.CPtr) -> BYTEPTR: if not out_len: zipfile_set_error(ZIP_ERR_OPEN, "out_len is None") return None - f: fio.File | t.CPtr = fio.File(path, fio.MODE.R) - if f.closed: - zipfile_set_error(ZIP_ERR_OPEN, "cannot open file for reading") + h: wb.HANDLE = wf.CreateFileA( + path, wf.GENERIC_READ, zf_share_flags(), + None, wf.OPEN_EXISTING, wf.FILE_ATTRIBUTE_NORMAL, None) + if h == wb.INVALID_HANDLE_VALUE: + zipfile_set_error_win(ZIP_ERR_OPEN, "cannot open file for reading", wb.GetLastError()) return None - sz64: LONGLONG = f.size() - if sz64 < 0: - f.close() + li: wb.LARGE_INTEGER = wb.LARGE_INTEGER() + ok_size: BOOL = wf.GetFileSizeEx(h, t.CPtr(c.Addr(li))) + if ok_size == 0: + wb.CloseHandle(h) zipfile_set_error(ZIP_ERR_IO, "cannot get file size") return None - sz: t.CSizeT = t.CSizeT(sz64) + sz: t.CSizeT = t.CSizeT(li.QuadPart) if sz == 0: - f.close() + wb.CloseHandle(h) zipfile_set_error(ZIP_ERR_NOT_ZIP, "empty file is not a zip archive") return None buf: BYTEPTR = BYTEPTR(stdlib.malloc(sz)) if not buf: - f.close() + wb.CloseHandle(h) zipfile_set_error(ZIP_ERR_MEMORY, "out of memory") return None - rc: t.CInt = zf_fread_all(f, buf, sz) - f.close() + rc: t.CInt = zf_read_all(h, buf, sz) + wb.CloseHandle(h) if rc != ZIP_ERR_OK: stdlib.free(buf) return None @@ -186,8 +217,11 @@ def zf_read_whole(path: str, out_len: t.CSizeT | t.CPtr) -> BYTEPTR: # ============================================================ # 条目信息(目录项) +# 注意: 节点为显式 calloc 分配(@t.Object 裸结构,无 GC 追踪), +# 由 ZipFile 负责释放——避免 GC 实例经 | t.CPtr 联合字段引用被回收。 # ============================================================ +@t.Object class ZipInfo: filename: bytes # 原始字节名(含 \0,zipfile 持有并负责释放) name_len: t.CSizeT @@ -198,16 +232,6 @@ class ZipInfo: header_offset: t.CSizeT # 本地文件头偏移 next: "ZipInfo" | t.CPtr # 链表(保持写入/目录顺序) - def __init__(self): - self.filename = None - self.name_len = 0 - self.compress_type = ZIP_STORED - self.crc32 = 0 - self.compress_size = 0 - self.file_size = 0 - self.header_offset = 0 - self.next = None - # ============================================================ # ZipFile @@ -217,7 +241,7 @@ class ZipFile: path: bytes mode: t.CInt # 0 = 读,1 = 写 compression: t.CInt # write() 未显式指定时的压缩类型 - fh: fio.File | t.CPtr # 写模式句柄 + fh: wb.HANDLE # 写模式句柄(裸 win32 CreateFileA) data: BYTEPTR # 读模式:整个归档的内存副本 data_len: t.CSizeT info_head: ZipInfo | t.CPtr @@ -240,9 +264,10 @@ class ZipFile: self.pos = 0 self.ok = 0 self.closed = 0 - if mode == "r": + # 注意: 字符串必须用 strcmp 比较(== 只会比较指针) + if string.strcmp(mode, "r") == 0: self.mode = 0 - elif mode == "w": + elif string.strcmp(mode, "w") == 0: self.mode = 1 else: zipfile_set_error(ZIP_ERR_OPEN, "mode must be 'r' or 'w'") @@ -261,9 +286,11 @@ class ZipFile: self.closed = 1 return else: - self.fh = fio.File(path, fio.MODE.W) - if self.fh.closed: - zipfile_set_error(ZIP_ERR_OPEN, "cannot create file for writing") + self.fh = wf.CreateFileA( + path, wf.GENERIC_WRITE, zf_share_flags(), + None, wf.CREATE_ALWAYS, wf.FILE_ATTRIBUTE_NORMAL, None) + if self.fh == wb.INVALID_HANDLE_VALUE: + zipfile_set_error_win(ZIP_ERR_OPEN, "cannot create file for writing", wb.GetLastError()) self.fh = None self.closed = 1 return @@ -278,13 +305,18 @@ class ZipFile: n.filename = None nxt: ZipInfo | t.CPtr = n.next n.next = None + stdlib.free(n) n = nxt self.info_head = None self.info_tail = None self.info_count = 0 def _append_info(self) -> ZipInfo | t.CPtr: - node: ZipInfo | t.CPtr = ZipInfo() + node: ZipInfo | t.CPtr = stdlib.calloc(1, ZipInfo.__sizeof__()) + if not node: + zipfile_set_error(ZIP_ERR_MEMORY, "out of memory") + return None + node.next = None if self.info_tail is None: self.info_head = node else: @@ -354,6 +386,9 @@ class ZipFile: zipfile_set_error(ZIP_ERR_MEMORY, "out of memory") return ZIP_ERR_MEMORY node: ZipInfo | t.CPtr = self._append_info() + if node is None: + stdlib.free(dup) + return ZIP_ERR_MEMORY node.filename = dup node.name_len = t.CSizeT(nlen) node.compress_type = t.CInt(method) @@ -514,12 +549,12 @@ class ZipFile: zf_w32le(hdr + 18, t.CUInt32T(plen)) zf_w32le(hdr + 22, t.CUInt32T(data_len)) zf_w16le(hdr + 26, t.CUInt32T(name_len)) - rc: t.CInt = zf_fwrite_all(self.fh, hdr, 30) + rc: t.CInt = zf_write_all(self.fh, hdr, 30) stdlib.free(hdr) if rc == ZIP_ERR_OK: - rc = zf_fwrite_all(self.fh, arcname, name_len) + rc = zf_write_all(self.fh, arcname, name_len) if rc == ZIP_ERR_OK: - rc = zf_fwrite_all(self.fh, payload, plen) + rc = zf_write_all(self.fh, payload, plen) if ctype == ZIP_DEFLATED: stdlib.free(payload) if rc != ZIP_ERR_OK: @@ -531,6 +566,9 @@ class ZipFile: zipfile_set_error(ZIP_ERR_MEMORY, "out of memory") return ZIP_ERR_MEMORY node: ZipInfo | t.CPtr = self._append_info() + if node is None: + stdlib.free(dup) + return ZIP_ERR_MEMORY node.filename = dup node.name_len = name_len node.compress_type = ctype @@ -565,9 +603,11 @@ class ZipFile: zf_w32le(hdr + 24, t.CUInt32T(n.file_size)) zf_w16le(hdr + 28, t.CUInt32T(n.name_len)) zf_w32le(hdr + 42, t.CUInt32T(n.header_offset)) - rc = zf_fwrite_all(self.fh, hdr, 46) + rc = zf_write_all(self.fh, hdr, 46) if rc == ZIP_ERR_OK: - rc = zf_fwrite_all(self.fh, n.filename, n.name_len) + rc = zf_write_all(self.fh, n.filename, n.name_len) + if rc == ZIP_ERR_OK: + self.pos = self.pos + 46 + n.name_len n = n.next stdlib.free(hdr) if rc != ZIP_ERR_OK: @@ -584,7 +624,7 @@ class ZipFile: zf_w16le(e + 10, t.CUInt32T(self.info_count)) zf_w32le(e + 12, t.CUInt32T(cd_size)) zf_w32le(e + 16, t.CUInt32T(cd_start)) - rc = zf_fwrite_all(self.fh, e, 22) + rc = zf_write_all(self.fh, e, 22) stdlib.free(e) if rc != ZIP_ERR_OK: zipfile_set_error(ZIP_ERR_IO, "write EOCD failed") @@ -596,7 +636,7 @@ class ZipFile: rc: t.CInt = ZIP_ERR_OK if self.mode == 1 and self.fh is not None: rc = self._finish_write() - self.fh.close() + wb.CloseHandle(self.fh) self.fh = None elif self.mode == 0: if self.data is not None: diff --git a/zlib/zdeflate.vp b/zlib/zdeflate.vp index e79efda..20860ce 100644 --- a/zlib/zdeflate.vp +++ b/zlib/zdeflate.vp @@ -52,8 +52,11 @@ class zdeflate_stream: attempts += 1 return best_len if (best_len >= zdef.ZDEFLATE_MIN_MATCH) else 0 - def update_hash(self, data: BYTE | t.CPtr, pos: t.CSizeT): - if pos + 2 < pos: return + def update_hash(self, data: BYTE | t.CPtr, pos: t.CSizeT, data_len: t.CSizeT): + # 只在还能作为匹配起点的位置维护 hash(pos+2 >= data_len 的尾部 + # 字节不会再被 find_match 引用,且 zdeflate_hash 会读 pos..pos+2, + # 越过末尾则越界——见 ASan heap-buffer-overflow) + if pos + 2 >= data_len: return h: t.CUnsignedInt = zdeflate_hash(data + pos) self.hash_prev[pos & zdef.ZDEFLATE_WINDOW_MASK] = self.hash_head[h] self.hash_head[h] = t.CInt(pos) @@ -83,11 +86,11 @@ class zdeflate_stream: if extra > 0: self.writer.write_bits(best_dist - zdef.zdeflate_dist_base[dist_sym], extra) for i in range(match_len): - self.update_hash(data, pos + i) + self.update_hash(data, pos + i, length) pos += match_len else: lit_tree.encode_symbol(data[pos], c.Addr(self.writer)) - self.update_hash(data, pos) + self.update_hash(data, pos, length) pos += 1 lit_tree.encode_symbol(256, c.Addr(self.writer)) @@ -111,11 +114,11 @@ class zdeflate_stream: if extra > 0: self.writer.write_bits(best_dist - zdef.zdeflate_dist_base[dist_sym], extra) for j in range(match_len): - self.update_hash(data, pos + j) + self.update_hash(data, pos + j, length) pos += match_len else: lit_tree.encode_symbol(data[pos], c.Addr(self.writer)) - self.update_hash(data, pos) + self.update_hash(data, pos, length) pos += 1 lit_tree.encode_symbol(256, c.Addr(self.writer)) @@ -270,11 +273,11 @@ def zdeflate_count_freqs(lit_freqs: INTPTR, dist_freqs: INTPTR, lit_freqs[len_sym] += 1 dist_freqs[zdeflate_dist_to_symbol(best_dist)] += 1 for i in range(match_len): - zdeflate_stream.update_hash(s, data, pos + i) + zdeflate_stream.update_hash(s, data, pos + i, length) pos += match_len else: lit_freqs[data[pos]] += 1 - zdeflate_stream.update_hash(s, data, pos) + zdeflate_stream.update_hash(s, data, pos, length) pos += 1 lit_freqs[256] = 1 @@ -329,7 +332,9 @@ def zdeflate_count_cl_freqs(all_lengths: INTPTR, total: t.CInt, cl_freqs: INTPTR if count > 6: count = 6 cl_freqs[16] += 1 run -= count - i += run + i += count + # 剩余的 1~2 个相同长度值不静默跳过,交由外层循环 + # 按字面量(符号 val)逐个统计,保证总覆盖数恰为 total def zdeflate_write_cl_encoded(all_lengths: INTPTR, total: t.CInt, w: zdef.zbit_writer | t.CPtr, cl_tree: zhuff.zhuff_tree | t.CPtr): @@ -367,7 +372,9 @@ def zdeflate_write_cl_encoded(all_lengths: INTPTR, total: t.CInt, cl_tree.encode_symbol(16, w) w.write_bits(count - 3, 2) run -= count - i += run + i += count + # 剩余的 1~2 个相同长度值不静默跳过,交由外层循环 + # 按字面量(符号 val)逐个编码,保证 RLE 覆盖总数恰为 total diff --git a/zlib/zinflate.vp b/zlib/zinflate.vp index 18cc5b4..4eabcd5 100644 --- a/zlib/zinflate.vp +++ b/zlib/zinflate.vp @@ -70,7 +70,8 @@ class zinflate_stream: self.is_gzip = 1 if self.input_pos + 10 > self.input_len: return -3 self.input_pos += 10 - flg: BYTE = self.input_data[self.input_pos - 6] + # FLG 位于 gzip 头第 4 字节(偏移 3),即 self.input_pos - 7 + flg: BYTE = self.input_data[self.input_pos - 7] if flg & 0x04: if self.input_pos + 2 > self.input_len: return -3 xlen: UINT = self.input_data[self.input_pos] | (self.input_data[self.input_pos + 1] << 8)