From fb53f888939408bb0373f58d9372571ce66a89e7 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 5 Oct 2026 15:33:58 +0800 Subject: [PATCH] =?UTF-8?q?refactor(gen):=20R12/R13=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E2=80=94=E2=80=94=E4=B8=8B=E6=A0=87=20while=20=E5=BE=AA?= =?UTF-8?q?=E7=8E=AF=E6=94=B9=20for=20range=E3=80=81=E5=8E=BB=20c.Set?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与 includes 同步执行两批源改写:R12 把「i: int = 0 与 while i < N: … i += 1」形式的计数循环改写为「for i in range(N):」;R13 把 c.Set(*p, v) 迁移为 *p = v、c.Set(a, b) 迁移为 a = b(c.Set 是正在退化的路径)。 验证:bootstrap 三重重编 SUCCESS(无 vast_c 解析回退);全量 77/77 顺序回归通过(WebTest 首轮网络超时,单独重跑通过)。 --- App/lib/Phase/BuildPipeline.vp | 48 ++++---------- App/lib/Projectrans/Config.vp | 8 +-- App/lib/Stub/StubGen/Converter.vp | 52 ++++----------- App/lib/Stub/StubGen/VpiReader.vp | 20 ++---- App/lib/Stub/StubMerger/StubMergerStore.vp | 8 +-- App/lib/core/Gen/AssignGenMixin.vp | 4 +- App/lib/core/Gen/Call/CallGenBase.vp | 10 +-- App/lib/core/Gen/Call/CallGenCall.vp | 16 ++--- App/lib/core/Gen/Call/CallGenCtor.vp | 12 ++-- App/lib/core/Gen/Call/CallGenDispatch.vp | 4 +- App/lib/core/Gen/Call/CallGenLeafKit.vp | 10 +-- App/lib/core/Gen/Call/CallGenProp.vp | 8 +-- App/lib/core/Gen/Expr/ExprGenAttr.vp | 8 +-- App/lib/core/Gen/Expr/ExprGenCdef.vp | 20 ++---- App/lib/core/Gen/Expr/ExprGenOps.vp | 4 +- App/lib/core/Gen/ImportsGenMixin.vp | 24 ++----- App/lib/core/Gen/StructGenMixin.vp | 12 +--- App/lib/core/Gen/Translator.vp | 16 ++--- App/lib/core/Gen/TranslatorGenMixin.vp | 12 +--- App/lib/core/Gen/Type/TypeGenCDef.vp | 8 +-- App/lib/core/Gen/Type/TypeGenCType.vp | 12 +--- App/lib/core/Gen/Type/TypeGenResolve.vp | 50 +++++--------- App/lib/core/Gen/Type/TypeSpec.vp | 24 ++----- App/lib/core/Repl.vp | 12 +--- App/lib/core/builtin/ViperBuild.vp | 76 ++++++---------------- 25 files changed, 133 insertions(+), 345 deletions(-) diff --git a/App/lib/Phase/BuildPipeline.vp b/App/lib/Phase/BuildPipeline.vp index cec0044..a095e38 100644 --- a/App/lib/Phase/BuildPipeline.vp +++ b/App/lib/Phase/BuildPipeline.vp @@ -940,12 +940,10 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet, linker_cmd: str, link dt2len: sizet = dj - ds2 if dt2len == dtlen: deq: int = 1 - dk: sizet = 0 - while dk < dtlen: + for dk in range(dtlen): if dedup[ds2 + dk] != obj_paths[dstart + dk]: deq = 0 break - dk += 1 if deq != 0: ddup = 1 break @@ -1304,18 +1302,14 @@ def _tb_quoted_after(mb: memhub.MemBuddy*, s: str, key: str) -> str: def _tb_dir_lookup(dirs: bytes, count: int, idx: int) -> str: - i: int = 0 - while i < count: + for i in range(count): if int(_tb_rd_u32(dirs, sizet(i) * TB_DIR_SIZE)) == idx: return rawptr(_tb_rd_u64(dirs, sizet(i) * TB_DIR_SIZE + 8)) - i += 1 return None def _tb_file_rec(files: bytes, count: int, idx: int) -> int: - i: int = 0 - while i < count: + for i in range(count): if int(_tb_rd_u32(files, sizet(i) * TB_FILE_SIZE)) == idx: return i - i += 1 return -1 @@ -1407,11 +1401,9 @@ def _tb_func_name_for(fbuf: bytes, fcount: int, rva: uint64) -> str: def _tb_intern(p: TbPool*, s: str) -> uint64: """Intern s into the pool (linear scan; keeps offset 0 as the empty sentinel).""" if p is None or s is None: return 0 - k: int = 0 - while k < p.OffCount: + for k in range(p.OffCount): o: uint64 = _tb_rd_u64(p.Offs, sizet(k) * 8) if string.strcmp(p.Pool + sizet(o), s) == 0: return o - k += 1 off: uint64 = uint64(p.PoolLen) n: sizet = string.strlen(s) string.memcpy(p.Pool + sizet(off), s, n) @@ -1456,8 +1448,7 @@ def _tb_read_pe_layout(mb: memhub.MemBuddy*, exe_path: str) -> TbPeLayout*: min_rva: uint64 = 0xFFFFFFFF found_text: int = 0 have_sec: int = 0 - si: uint64 = 0 - while si < nsec: + for si in range(nsec): base: sizet = sec_off + sizet(si) * 40 if uint64(base) + 40 > uint64(got): break va: uint64 = uint64(_tb_rd_u32(head, base + 12)) @@ -1466,7 +1457,6 @@ def _tb_read_pe_layout(mb: memhub.MemBuddy*, exe_path: str) -> TbPeLayout*: if _tb_cc(head, base) == 46 and _tb_cc(head, base + 1) == 116 and _tb_cc(head, base + 2) == 101 and _tb_cc(head, base + 3) == 120 and _tb_cc(head, base + 4) == 116: text_rva = va found_text = 1 - si += 1 if found_text == 0 and have_sec != 0 and min_rva != 0xFFFFFFFF: text_rva = min_rva lay.ImageBase = img_base lay.SizeOfImage = size_img @@ -1752,8 +1742,7 @@ def _tb_grp_get(grp: bytes, cap: int, caller: str, callee: str, do_insert: int) if grp is None or cap <= 0 or caller is None or callee is None: return -1 mask: uint64 = uint64(cap - 1) hv: uint64 = (_tb_strhash(caller) * 0x100000001B3 + _tb_strhash(callee)) & mask - i: int = 0 - while i < cap: + for i in range(cap): slot: int = int((hv + uint64(i)) & mask) off: sizet = sizet(slot) * TB_GRP_SIZE if uint64(_tb_rd_u32(grp, off + TB_GRP_OFF_USED)) == 0: @@ -1768,7 +1757,6 @@ def _tb_grp_get(grp: bytes, cap: int, caller: str, callee: str, do_insert: int) sc: str = rawptr(_tb_rd_u64(grp, off + TB_GRP_OFF_CALLER)) sk: str = rawptr(_tb_rd_u64(grp, off + TB_GRP_OFF_CALLEE)) if sc is not None and sk is not None and string.strcmp(sc, caller) == 0 and string.strcmp(sk, callee) == 0: return slot - i += 1 return -1 @@ -1910,13 +1898,11 @@ def _tb_parse_vpcall_file(mb: memhub.MemBuddy*, path: str, cp: TbCallParse*) -> def _tb_load_vpcalls(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int: if _tb_vpcall_buf is None or _tb_vpcall_n <= 0: return 0 - k: int = 0 - while k < _tb_vpcall_n: + for k in range(_tb_vpcall_n): slot: str* = (str*)(uint64(_tb_vpcall_buf) + sizet(k) * 8) path: str = slot[0] if path is not None: if _tb_parse_vpcall_file(mb, path, cp) != 0: return 1 - k += 1 return 0 @@ -1929,8 +1915,7 @@ def _tb_build_groups(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int: VLogger.error("--traceback: 调用点分组表分配失败,终止编译", "TRACEBACK") return 1 string.memset(cp.Grp, 0, sizet(cp.GrpCap) * TB_GRP_SIZE) - i: int = 0 - while i < cp.CrN: + for i in range(cp.CrN): off: sizet = sizet(i) * TB_CR_SIZE caller: str = rawptr(_tb_rd_u64(cp.Cr, off + TB_CR_OFF_CALLER)) callee: str = rawptr(_tb_rd_u64(cp.Cr, off + TB_CR_OFF_CALLEE)) @@ -1948,7 +1933,6 @@ def _tb_build_groups(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int: _tb_wr_u32(cp.Cr, toff + TB_CR_OFF_NEXT, uint64(i)) _tb_wr_u32(cp.Cr, off + TB_CR_OFF_NEXT, uint64(TB_IDX_NONE)) _tb_wr_u32(cp.Grp, goff + TB_GRP_OFF_TAIL, uint64(i)) - i += 1 return 0 @@ -1972,15 +1956,13 @@ def _tb_emit_call_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo def _tb_emit_entry_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo: uint64, addr: uint64, sym: str) -> int: """Emit a fallback function-entry row for an objdump label sym (file/line from the F record).""" if sym is None or cp.Fr is None or cp.FrN <= 0 or addr < img_lo: return 0 - i: int = 0 - while i < cp.FrN: + for i in range(cp.FrN): off: sizet = sizet(i) * TB_FR_SIZE s: str = rawptr(_tb_rd_u64(cp.Fr, off + TB_FR_OFF_SYM)) if s is not None and string.strcmp(s, sym) == 0: file: str = rawptr(_tb_rd_u64(cp.Fr, off + TB_FR_OFF_FILE)) dl: int = int(_tb_rd_u32(cp.Fr, off + TB_FR_OFF_DEFLINE)) return _tb_emit_row(mb, d, addr, file, dl, sym) - i += 1 return 0 @@ -2298,8 +2280,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: if ro is None: VLogger.error("--traceback: 记录偏移缓冲分配失败,终止编译", "TRACEBACK") return 1 - i = 0 - while i < uniq: + for i in range(uniq): pth2: str = rawptr(_tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FILE)) foff: uint64 = _tb_intern(p, pth2) noff: uint64 = 0 @@ -2311,7 +2292,6 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: if nm2 is not None: noff = _tb_intern(p, nm2) _tb_wr_u32(ro, sizet(i) * 8, foff) _tb_wr_u32(ro, sizet(i) * 8 + 4, noff) - i += 1 # ---- 5) self-checks (mirror the runtime LoadMapFile validation) ---- prev_rva: uint64 = 0 @@ -2335,13 +2315,11 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: return 1 # file_off must be >= 1: offset 0 is the empty-string sentinel and the runtime # rejects a whole map whose record file_off is 0. - ci = 0 - while ci < uniq: + for ci in range(uniq): fo: uint64 = uint64(_tb_rd_u32(ro, sizet(ci) * 8)) if fo == 0: VLogger.error("--traceback 自检失败:存在 file_off==0 的记录(空路径,运行期会拒绝该旁文件),终止编译", "TRACEBACK") return 1 - ci += 1 # ---- 6) serialise and write .stackmap ---- total: sizet = 20 + sizet(uniq) * 20 + sizet(p.PoolLen) @@ -2357,8 +2335,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: _tb_wr_u32(out, 8, uint64(uniq)) _tb_wr_u32(out, 12, uint64(p.OffCount)) _tb_wr_u32(out, 16, uint64(p.PoolLen)) - ri2: int = 0 - while ri2 < uniq: + for ri2 in range(uniq): roff2: sizet = 20 + sizet(ri2) * 20 rv3: uint64 = _tb_rd_u64(d.RowBuf, sizet(ri2) * TB_ROW_SIZE) ln3: uint64 = uint64(_tb_rd_u32(d.RowBuf, sizet(ri2) * TB_ROW_SIZE + TB_ROW_OFF_LINE)) @@ -2366,7 +2343,6 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int: _tb_wr_u32(out, roff2 + 8, uint64(_tb_rd_u32(ro, sizet(ri2) * 8))) _tb_wr_u32(out, roff2 + 12, ln3) _tb_wr_u32(out, roff2 + 16, uint64(_tb_rd_u32(ro, sizet(ri2) * 8 + 4))) - ri2 += 1 string.memcpy(out + 20 + sizet(uniq) * 20, p.Pool, sizet(p.PoolLen)) map_len: sizet = string.strlen(exe_path) + 16 diff --git a/App/lib/Projectrans/Config.vp b/App/lib/Projectrans/Config.vp index 967a09d..dcb47fa 100644 --- a/App/lib/Projectrans/Config.vp +++ b/App/lib/Projectrans/Config.vp @@ -267,8 +267,7 @@ def _normalize_path(path: str) -> str: seg_start: sizet = 0 out_len: sizet = 0 has_seg: int = 0 - i: sizet = 0 - while i <= plen: + for i in range(plen + 1): ch: char = '\0' if i < plen: ch = path[i] if ch == '/' or ch == '\\' or ch == '\0': @@ -313,7 +312,6 @@ def _normalize_path(path: str) -> str: jj += 1 has_seg = 1 seg_start = i + 1 - i += 1 if has_seg == 0: # All segments consumed (e.g. ./..): return current dir return "./" @@ -577,8 +575,7 @@ def slice_subdir(sha1: str, level: int) -> str: buf: str = _mbuddy.alloc(buf_len) if buf is None: return None pos: int = 0 - i: int = 0 - while i < level: + for i in range(level): if i > 0: buf[pos] = '/' pos += 1 @@ -586,6 +583,5 @@ def slice_subdir(sha1: str, level: int) -> str: buf[pos] = sha1[idx] buf[pos + 1] = sha1[idx + 1] pos += 2 - i += 1 buf[pos] = '\0' return buf \ No newline at end of file diff --git a/App/lib/Stub/StubGen/Converter.vp b/App/lib/Stub/StubGen/Converter.vp index a6cffda..848bf5e 100644 --- a/App/lib/Stub/StubGen/Converter.vp +++ b/App/lib/Stub/StubGen/Converter.vp @@ -98,7 +98,7 @@ def _lookup_cdefine_for_pyi(name: str) -> int64: global _g_pyi_cdefine_found # Look up this file's CDefine cache first (globals are empty during vpi gen) if _g_pyi_cdef_names is not None and _g_pyi_cdef_vals is not None: - # Bound loop by _g_pyi_cdef_count; never len()/.get on i8** (len falls back + # Bound loop by _g_pyi_cdef_count; never len()/.get on i8** (len falls back # to strlen, .get misdispatches to HashTable.get) -- index via t.CPtr(base + i*8). pn: sizet = sizet(_g_pyi_cdef_count) for pi in range(pn): @@ -160,10 +160,8 @@ def _PyiEmit(buf: bytes, buf_size: sizet, pos: sizet, text: str) -> sizet: # _PyiIndent - append level*4 spaces to buf at pos def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet, level: int) -> sizet: """Append level*4 spaces to buf at pos and return the new pos""" - i: int = 0 - while i < level: + for i in range(level): pos = _PyiEmit(buf, buf_size, pos, " ") - i += 1 return pos @@ -249,8 +247,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth: cmps_ct: list[ast.AST*]* = cmp_t.comparators if ops_ct is not None: on_ct: sizet = len(ops_ct) - oi_ct: sizet = 0 - while oi_ct < on_ct: + for oi_ct in range(on_ct): oid_ct: int = ops_ct.get(oi_ct) if oid_ct == ast.OpKind.Eq: pos = _PyiEmit(buf, buf_size, pos, " == ") elif oid_ct == ast.OpKind.Ne: pos = _PyiEmit(buf, buf_size, pos, " != ") @@ -262,7 +259,6 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth: # TPC indexes comparators[i] by ops; guard the length here so a # malformed AST (unequal ops/comparators) cannot overrun. if cmps_ct is not None and oi_ct < len(cmps_ct): pos = _PyiTypeStr(buf, buf_size, pos, cmps_ct.get(oi_ct), depth + 1) - oi_ct += 1 return pos # BoolOp: boolean ops (ENABLED and MAX_SIZE > 0 / A or B). @@ -272,13 +268,11 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth: vals_bt: list[ast.AST*]* = bool_t.values if vals_bt is not None: vn_bt: sizet = len(vals_bt) - vi_bt: sizet = 0 - while vi_bt < vn_bt: + for vi_bt in range(vn_bt): if vi_bt > 0: if bool_t.op == ast.OpKind.Or: pos = _PyiEmit(buf, buf_size, pos, " or ") else: pos = _PyiEmit(buf, buf_size, pos, " and ") pos = _PyiTypeStr(buf, buf_size, pos, vals_bt.get(vi_bt), depth + 1) - vi_bt += 1 return pos # Constant: string forward refs (e.g. 'MyClass'), None or numeric constants @@ -309,12 +303,10 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth: if lst.elts is not None: lst_elts: list[ast.AST*]* = lst.elts ln: sizet = len(lst_elts) - li: sizet = 0 - while li < ln: + for li in range(ln): if li > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") le: ast.AST* = lst_elts.get(li) pos = _PyiTypeStr(buf, buf_size, pos, le, depth + 1) - li += 1 pos = _PyiEmit(buf, buf_size, pos, "]") return pos @@ -324,12 +316,10 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth: if tup.elts is not None: tup_elts: list[ast.AST*]* = tup.elts tn: sizet = len(tup_elts) - ti: sizet = 0 - while ti < tn: + for ti in range(tn): if ti > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") el: ast.AST* = tup_elts.get(ti) pos = _PyiTypeStr(buf, buf_size, pos, el, depth + 1) - ti += 1 return pos # Call: call expression (used by decorators such as @t.NoVTable()) @@ -340,12 +330,10 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth: if cl.args is not None: cl_args: list[ast.AST*]* = cl.args can: sizet = len(cl_args) - cai: sizet = 0 - while cai < can: + for cai in range(can): if cai > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") ca: ast.AST* = cl_args.get(cai) pos = _PyiTypeStr(buf, buf_size, pos, ca, depth + 1) - cai += 1 pos = _PyiEmit(buf, buf_size, pos, ")") return pos @@ -437,15 +425,13 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, fn: ast.FunctionDef*, if fn.decorator_list is not None: fn_decorator_list: list[ast.AST*]* = fn.decorator_list dn: sizet = len(fn_decorator_list) - di: sizet = 0 - while di < dn: + for di in range(dn): dec: ast.AST* = fn_decorator_list.get(di) if dec is not None: pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiEmit(buf, buf_size, pos, "@") pos = _PyiTypeStr(buf, buf_size, pos, dec) pos = _PyiEmit(buf, buf_size, pos, "\n") - di += 1 pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiEmit(buf, buf_size, pos, "def ") @@ -521,15 +507,13 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cls: ast.ClassDef*, inden if cls.decorator_list is not None: cls_decorator_list: list[ast.AST*]* = cls.decorator_list dcn: sizet = len(cls_decorator_list) - dci: sizet = 0 - while dci < dcn: + for dci in range(dcn): ddec: ast.AST* = cls_decorator_list.get(dci) if ddec is not None: pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiEmit(buf, buf_size, pos, "@") pos = _PyiTypeStr(buf, buf_size, pos, ddec) pos = _PyiEmit(buf, buf_size, pos, "\n") - dci += 1 pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiEmit(buf, buf_size, pos, "class ") @@ -543,12 +527,10 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cls: ast.ClassDef*, inden tpn: sizet = len(cls_type_params) if tpn > 0: pos = _PyiEmit(buf, buf_size, pos, "[") - tpi: sizet = 0 - while tpi < tpn: + for tpi in range(tpn): if tpi > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") tpname: str = cls_type_params.get(tpi) if tpname is not None: pos = _PyiEmit(buf, buf_size, pos, tpname) - tpi += 1 pos = _PyiEmit(buf, buf_size, pos, "]") # Base classes @@ -557,12 +539,10 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cls: ast.ClassDef*, inden bn: sizet = len(cls_bases) if bn > 0: pos = _PyiEmit(buf, buf_size, pos, "(") - bi: sizet = 0 - while bi < bn: + for bi in range(bn): if bi > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") base: ast.AST* = cls_bases.get(bi) pos = _PyiTypeStr(buf, buf_size, pos, base) - bi += 1 pos = _PyiEmit(buf, buf_size, pos, ")") pos = _PyiEmit(buf, buf_size, pos, ":\n") @@ -736,8 +716,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf if imp2.names is not None: imp2_names: list[ast.AST*]* = imp2.names an2: sizet = len(imp2_names) - ai2: sizet = 0 - while ai2 < an2: + for ai2 in range(an2): if ai2 > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") al2: ast.Alias* = ast.Alias*(imp2_names.get(ai2)) # fail-fast: never silently write "import , ". Import names are the @@ -750,7 +729,6 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf if al2.asname is not None and string.strlen(al2.asname) > 0: pos = _PyiEmit(buf, buf_size, pos, " as ") pos = _PyiEmit(buf, buf_size, pos, al2.asname) - ai2 += 1 pos = _PyiEmit(buf, buf_size, pos, "\n") # ImportFrom statement @@ -770,8 +748,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf if ifr.names is not None: ifr_names: list[ast.AST*]* = ifr.names an3: sizet = len(ifr_names) - ai3: sizet = 0 - while ai3 < an3: + for ai3 in range(an3): if ai3 > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") al3: ast.Alias* = ast.Alias*(ifr_names.get(ai3)) # fail-fast: same as Import (report the two causes separately). @@ -783,7 +760,6 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf if al3.asname is not None and string.strlen(al3.asname) > 0: pos = _PyiEmit(buf, buf_size, pos, " as ") pos = _PyiEmit(buf, buf_size, pos, al3.asname) - ai3 += 1 pos = _PyiEmit(buf, buf_size, pos, "\n") # Function definition (_PyiFunction already ends with a newline) @@ -827,7 +803,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf viperlib.snprintf(num_buf, 32, " = %lld", cv.int_val) pos = _PyiEmit(buf, buf_size, pos, num_buf) elif cv.const_kind == ast.CONST_FLOAT: - # Float CDefines (e.g. numpy pi/e) must emit a value or read-back + # Float CDefines (e.g. numpy pi/e) must emit a value or read-back # degrades to a global pointer; %.17g round-trips double exactly. fbuf_c: bytes = mb.alloc(64) if fbuf_c is not None: diff --git a/App/lib/Stub/StubGen/VpiReader.vp b/App/lib/Stub/StubGen/VpiReader.vp index a6874a4..26c273a 100644 --- a/App/lib/Stub/StubGen/VpiReader.vp +++ b/App/lib/Stub/StubGen/VpiReader.vp @@ -148,8 +148,7 @@ def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, cap: int, key: h: uint64 = _vpi_idx_hash(key) mask: sizet = sizet(cap - 1) si: sizet = sizet(h) & mask - i: int = 0 - while i < cap: + for i in range(cap): slot: sizet* = _vpi_idx_slot(idx_base, si) sv: sizet = slot[0] if sv == 0: return -1 @@ -157,7 +156,6 @@ def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, cap: int, key: ek: bytes = keys + se * key_stride if string.strcmp(ek, key) == 0: return se si = (si + 1) & mask - i += 1 return -1 @@ -167,14 +165,12 @@ def _vpi_idx_insert(idx_base: bytes, cap: int, slot_index: int, key: bytes) -> i h: uint64 = _vpi_idx_hash(key) mask: sizet = sizet(cap - 1) si: sizet = sizet(h) & mask - i: int = 0 - while i < cap: + for i in range(cap): slot: sizet* = _vpi_idx_slot(idx_base, si) if slot[0] == 0: slot[0] = sizet(slot_index + 1) return 0 si = (si + 1) & mask - i += 1 return 1 @@ -839,13 +835,11 @@ def _vpi_param_annot_seg_is(src_sha1: str, cls_name: str, method_name: str, seg_ prm: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name) if prm is None or prm[0] == '\0': return 0 cur: sizet = 0 - seg: int = 0 # locate segment start: skip seg_idx '@'-separated segments - while seg < seg_idx: + for seg in range(seg_idx): while prm[cur] != '\0' and prm[cur] != '@': cur += 1 if prm[cur] == '\0': return 0 cur += 1 - seg += 1 slen: sizet = 0 while prm[cur + slen] != '\0' and prm[cur + slen] != '@': slen += 1 wlen: sizet = string.strlen(want) @@ -1053,10 +1047,8 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*, seg: str) -> mlirlite.L star_off_ps: sizet = string.strlen(star_buf_ps) string.strncpy(star_buf_ps + star_off_ps, seg, star_base_end_ps) star_buf_ps[star_off_ps + star_base_end_ps] = '\0' - star_k_ps = 0 - while star_k_ps < star_cnt_ps: + for star_k_ps in range(star_cnt_ps): string.strcat(star_buf_ps, "]") - star_k_ps += 1 star_ty_ps: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, star_buf_ps) stdlib.free(star_buf_ps) return star_ty_ps @@ -1307,10 +1299,8 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, ret_annot: str, i32_ty: m if cptr_sub_lvl > 0: if first_ty is None: return cptr_sub_ty res_ty_cs: mlirlite.LLVMType* = first_ty - wrap_i_cs: int = 0 - while wrap_i_cs < cptr_sub_lvl: + for wrap_i_cs in range(cptr_sub_lvl): res_ty_cs = mlirlite.Ptr(pool, res_ty_cs) - wrap_i_cs += 1 return res_ty_cs if has_cvoid != 0: # t.CVoid | t.State: State is a decorator marker (ignored), t.CVoid -> void. diff --git a/App/lib/Stub/StubMerger/StubMergerStore.vp b/App/lib/Stub/StubMerger/StubMergerStore.vp index cfe661b..286b09c 100644 --- a/App/lib/Stub/StubMerger/StubMergerStore.vp +++ b/App/lib/Stub/StubMerger/StubMergerStore.vp @@ -416,12 +416,10 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str: if colon < total_len and from_imports[colon] == ':' and local_len == alias_len: # compare local_name == alias Matched: int = 1 - li: sizet = 0 - while li < alias_len: + for li in range(alias_len): if from_imports[ci + li] != alias[li]: Matched = 0 break - li += 1 if Matched == 1: # extract module (from colon+1 to next ':' or space) m_start: sizet = colon + 1 @@ -459,12 +457,10 @@ def LookupModNameByAlias(from_imports: str, alias: str) -> str: if colon < total_len and from_imports[colon] == ':' and local_len == alias_len: # compare local_name == alias Matched: int = 1 - li: sizet = 0 - while li < alias_len: + for li in range(alias_len): if from_imports[ci + li] != alias[li]: Matched = 0 break - li += 1 if Matched == 1: # extract module (from colon+1 to next ':' or space) m_start: sizet = colon + 1 diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index b135197..52a2c0d 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -721,15 +721,13 @@ novirtual class AssignGenMixin: n_s: sizet = string.strlen(sv_s) if sizet(arr_count) < n_s: self.Gen.TypeGenErr.fatal_error(list_node, f"字符串字面量长度 {n_s} 超过字符数组声明长度 {arr_count},不允许越界写入", "OverflowError") - bi_s: sizet = 0 - while bi_s < n_s: + for bi_s in range(n_s): bidx_s: mlirlite.Value* = mlirlite.const_int32(pool, bi_s) bp_s: mlirlite.Value* = mlirlite.build_gep_array(builder, arr_ty, elem_ty, array_alloca, bidx_s) if bp_s is None: break bvv: mlirlite.Value* = mlirlite.const_int32(pool, sv_s[bi_s]) bsv: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, bvv, elem_ty, e0_s) mlirlite.build_store(builder, bsv, bp_s) - bi_s += 1 return 0 # Element count exceeds declared length: fail fast (avoid out-of-range GEP writes) diff --git a/App/lib/core/Gen/Call/CallGenBase.vp b/App/lib/core/Gen/Call/CallGenBase.vp index 23e471f..edb34e5 100644 --- a/App/lib/core/Gen/Call/CallGenBase.vp +++ b/App/lib/core/Gen/Call/CallGenBase.vp @@ -182,12 +182,10 @@ novirtual class CallGenBase: fl2_od: sizet = fend_od - fstart_od if fl2_od == name_len: fd_eq_od: int = 1 - fdi_od: sizet = 0 - while fdi_od < fl2_od: + for fdi_od in range(fl2_od): if buf[fstart_od + fdi_od] != func_name[fdi_od]: fd_eq_od = 0 break - fdi_od += 1 if fd_eq_od != 0: has_own_def = 1 continue # line must start with "from " @@ -455,7 +453,7 @@ novirtual class CallGenBase: while cur is not None: cur_name: str = mlirlite.function_get_name(cur) if cur_name is not None: - # fast path: skip strcmp when first chars differ (mangled names start + # fast path: skip strcmp when first chars differ (mangled names start # with sha1 hex, bare names with letters/underscore) if cur_name[0] == name[0] and string.strcmp(cur_name, name) == 0: return cur # use Function.NameLen (computed once) instead of per-node strlen @@ -760,10 +758,8 @@ novirtual class CallGenBase: stdlib.free(nm_buf) if nm_ty is not None: nm_wrap: mlirlite.LLVMType* = nm_ty - nm_i: int = 0 - while nm_i < nm_star: + for nm_i in range(nm_star): nm_wrap = mlirlite.Ptr(pool, nm_wrap) - nm_i += 1 return nm_wrap # contains "*" -> generic i8* (i8*, i32*, { i32, i8 }*, unregistered %name*) diff --git a/App/lib/core/Gen/Call/CallGenCall.vp b/App/lib/core/Gen/Call/CallGenCall.vp index 73f9123..8710c9e 100644 --- a/App/lib/core/Gen/Call/CallGenCall.vp +++ b/App/lib/core/Gen/Call/CallGenCall.vp @@ -744,7 +744,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): if base_pfx_g != 0: base_clean_g = base_buf_g + sizet(base_pfx_g) spec_name_g: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, base_clean_g, ta_list_g) if spec_name_g is not None: - # Re-lookup the specialized function after specialization; + # Re-lookup the specialized function after specialization; # find_func_in_module matches both bare and tpl-prefixed names. spec_lk_g: str = pool.alloc(string.strlen(class_name) + string.strlen(method_name) + 2) if spec_lk_g is not None: @@ -871,7 +871,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): kwc: sizet = 0 if kw_calls is not None: kwc = len(kw_calls) - # Multi-inheritance this-adjust (byte-offset): delta = field offset in the + # Multi-inheritance this-adjust (byte-offset): delta = field offset in the # subclass minus in the parent layout; delta>0 GEPs and bitcasts to the parent. self_arg: mlirlite.Value* = obj_ptr if mc_anc is not None and string.strcmp(mc_anc, class_name) != 0: @@ -887,15 +887,13 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): # fields, so this needs no byte adjust; pass it through unchanged. if anc_entry_th is not None and anc_entry_th.FieldCount > 0: anc_first_name_th: str = None - afi_th: int = 0 - while afi_th < anc_entry_th.FieldCount: + for afi_th in range(anc_entry_th.FieldCount): afe_th: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(anc_entry_th, afi_th) if afe_th is not None: afn_th: str = self.Gen.StructGen.get_field_name_ptr(afe_th) if afn_th is not None and string.strcmp(afn_th, "__vtable__") != 0: anc_first_name_th = afn_th break - afi_th += 1 if anc_first_name_th is not None: sub_entry_th: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(class_name) if sub_entry_th is not None: @@ -1442,15 +1440,13 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): anc_entry_sp: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(anc) if anc_entry_sp is not None and anc_entry_sp.FieldCount > 0: first_name_sp: str = None - afi_sp: int = 0 - while afi_sp < anc_entry_sp.FieldCount: + for afi_sp in range(anc_entry_sp.FieldCount): afe_sp: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(anc_entry_sp, afi_sp) if afe_sp is not None: afn_sp: str = self.Gen.StructGen.get_field_name_ptr(afe_sp) if afn_sp is not None and string.strcmp(afn_sp, "__vtable__") != 0: first_name_sp = afn_sp break - afi_sp += 1 if first_name_sp is not None: sub_entry_sp: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(cur_class) if sub_entry_sp is not None: @@ -1563,12 +1559,10 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): e: GenTypes.StructEntry* = self.Gen.StructGen._get_struct_entry(j) if e is not None and e.Name is not None: pc: int = self.Gen.StructGen.get_parent_count(e.Name) - pj: int = 0 - while pj < pc: + for pj in range(pc): pn: str = self.Gen.StructGen.get_parent_name_at(e.Name, pj) if pn is not None: if string.strcmp(pn, class_name) == 0: return 1 - pj += 1 j += 1 return 0 diff --git a/App/lib/core/Gen/Call/CallGenCtor.vp b/App/lib/core/Gen/Call/CallGenCtor.vp index a773265..553f598 100644 --- a/App/lib/core/Gen/Call/CallGenCtor.vp +++ b/App/lib/core/Gen/Call/CallGenCtor.vp @@ -170,7 +170,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): # in translate_constant, else coercing an inttoptr char value as a pointer crashes). fe: GenTypes.FieldEntry* = None if ctor_entry is not None: - # Field 0 is __vtable__ (vtable pointer placeholder): ctor args must skip it, + # Field 0 is __vtable__ (vtable pointer placeholder): ctor args must skip it, # else an arg overwrites the vtable slot and isinstance/dispatch break. target_idx: int = 0 for fi in range(ctor_entry.FieldCount): @@ -494,7 +494,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if val_bits == 1: # i1 is a boolean (from icmp/fcmp) with unsigned semantics; must zext return mlirlite.build_zext(builder, val, target_ty) - # Unify the widening direction (same source as coerce_to_type's _zext_or_sext_val): + # Unify the widening direction (same source as coerce_to_type's _zext_or_sext_val): # i1/i8 -> zext; unsigned source -> zext; else sext (keeps the source's signedness). if self.Gen.ExprGenBase._zext_or_sext_val(pool, val, src_node, trans) != 0: return mlirlite.build_zext(builder, val, target_ty) return mlirlite.build_sext(builder, val, target_ty) @@ -558,7 +558,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): tn = self.Gen.TypeGenResolve._norm_type_arg_name(pool, tn_raw, from_imports) if tn is not None: result.append(tn) return result - # Generic-class ctor helper list[str](pool, 8): reuse translate_list_literal's flow (alloca, + # Generic-class ctor helper list[str](pool, 8): reuse translate_list_literal's flow (alloca, # arg array, __new__ -> __before_init__ -> __init__). Must not go through the normal call path. # _ptr_layer_type_arg - add the pointer layer (`*`) to inferred type args so the ctor side @@ -784,7 +784,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): tmp: mlirlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) if tmp is None: return None - # Translate args into a pointer array (extra_args[slot]): positional args -> slots + # Translate args into a pointer array (extra_args[slot]): positional args -> slots # 0..can-1; keywords -> slot by __init__ param name. Positional wins; order must not be assumed. cargs: list[ast.AST*]* = cl.args can: sizet = 0 @@ -840,12 +840,10 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): if slot_kw > arg_max_filled: arg_max_filled = slot_kw # Slots must be contiguous (0..arg_max_filled all filled): a hole means a param # got neither positional nor keyword arg. Never pass the hole as 0; fail-fast. - ci_hole: int = 0 - while ci_hole <= arg_max_filled: + for ci_hole in range(arg_max_filled + 1): if arg_filled[sizet(ci_hole)] == 0: self.Gen.TypeGenErr.fatal_error(cl, f"泛型类 '{tmpl_name}' 的关键字构造缺少前置形参(第 {ci_hole + 1} 个实参位置既无位置实参也无关键字实参)", "TypeError") break - ci_hole += 1 arg_count: int = 0 if arg_max_filled >= 0: arg_count = arg_max_filled + 1 diff --git a/App/lib/core/Gen/Call/CallGenDispatch.vp b/App/lib/core/Gen/Call/CallGenDispatch.vp index a5b13f9..ba2c286 100644 --- a/App/lib/core/Gen/Call/CallGenDispatch.vp +++ b/App/lib/core/Gen/Call/CallGenDispatch.vp @@ -171,8 +171,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): head: mlirlite.Value* = None tail: mlirlite.Value* = None fp: mlirlite.Param* = mlirlite.function_get_param_head(func) - ai: sizet = 0 - while ai < can: + for ai in range(can): arg: ast.AST* = cargs.get(ai) fpty: mlirlite.LLVMType* = None if fp is not None: fpty = mlirlite.param_get_ty(fp) @@ -185,7 +184,6 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): else: tail.Next = av tail = av if fp is not None: fp = mlirlite.param_get_next(fp) - ai += 1 # build_call's second arg is the callee name string (not Function*); passing a Function* # reads its first field as a string and emits illegal IR. Use the looked-up symbol name. return mlirlite.build_call(builder, spec_name, head, int(can), ret_ty, 0) diff --git a/App/lib/core/Gen/Call/CallGenLeafKit.vp b/App/lib/core/Gen/Call/CallGenLeafKit.vp index 999b473..a5883f6 100644 --- a/App/lib/core/Gen/Call/CallGenLeafKit.vp +++ b/App/lib/core/Gen/Call/CallGenLeafKit.vp @@ -65,8 +65,7 @@ def _gfn_idx_find(funcs: GenTypes.FuncEntry*, idx_base: sizet*, cap: int, name: mask: sizet = sizet(cap - 1) si: sizet = sizet(h) & mask entry_size: sizet = GenTypes.FuncEntry.__sizeof__() - i: int = 0 - while i < cap: + for i in range(cap): slot: sizet* = _gfn_idx_slot(idx_base, si) sv: sizet = slot[0] if sv == 0: return -1 @@ -76,7 +75,6 @@ def _gfn_idx_find(funcs: GenTypes.FuncEntry*, idx_base: sizet*, cap: int, name: if entry is not None and entry.Name is not None: if string.strcmp(entry.Name, name) == 0: return se si = (si + 1) & mask - i += 1 return -1 @@ -86,14 +84,12 @@ def _gfn_idx_insert(idx_base: sizet*, cap: int, slot_index: int, name: str) -> i h: uint64 = _gfn_hash(name) mask: sizet = sizet(cap - 1) si: sizet = sizet(h) & mask - i: int = 0 - while i < cap: + for i in range(cap): slot: sizet* = _gfn_idx_slot(idx_base, si) if slot[0] == 0: slot[0] = sizet(slot_index + 1) return 0 si = (si + 1) & mask - i += 1 return 1 @@ -936,7 +932,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin): return 0 - # _build_func_spec: build the full-signature TypeSpec (Kind=TS_FUNC) from a function after all + # _build_func_spec: build the full-signature TypeSpec (Kind=TS_FUNC) from a function after all # params are added; unlike SpecFromLLVMType's Func branch it carries func.IsVarArg. def _build_func_spec(self, func: mlirlite.Function*) -> TSpec.TypeSpec*: """Build the full-signature TypeSpec from a function; returns None on failure""" diff --git a/App/lib/core/Gen/Call/CallGenProp.vp b/App/lib/core/Gen/Call/CallGenProp.vp index cdf9358..86b2c82 100644 --- a/App/lib/core/Gen/Call/CallGenProp.vp +++ b/App/lib/core/Gen/Call/CallGenProp.vp @@ -116,13 +116,11 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): n_av: sizet = string.strlen(annot_val) last_dot_av: sizet = n_av depth_av: int = 0 - ai_av: sizet = 0 - while ai_av < n_av: + for ai_av in range(n_av): ch_av: int = annot_val[ai_av] if ch_av == '[': depth_av += 1 elif ch_av == ']': depth_av -= 1 elif ch_av == '.' and depth_av == 0: last_dot_av = ai_av - ai_av += 1 if last_dot_av < n_av: return annot_val + last_dot_av + 1 return annot_val return None @@ -263,7 +261,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): pfx: int = GenApi.sha1_prefix_len(name) return name + pfx if pfx != 0 else name - # _resolve_generic_receiver_name - resolve the receiver's actual generic specialization name (IR truth). + # _resolve_generic_receiver_name - resolve the receiver's actual generic specialization name (IR truth). # Strip the sha1 prefix, take the base before '['; bare generic base => fail-fast (D25), else None. def _resolve_generic_receiver_name(self, pool: memhub.MemBuddy*, struct_ty: mlirlite.LLVMType*, method_name: str, cl: ast.Call*) -> str: """Return the actual generic specialization name (sha1 stripped) or None; a bare generic base fails fast""" @@ -287,7 +285,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase): self.Gen.TypeGenErr.fatal_error(cl, f"方法 '{method_name}' 的接收者实际结构体类型是裸泛型基类 " f"'{short_nm}*'(丢失类型实参),元素类型未知;" f"禁止静默按默认元素类型处理(元素按 i32 处理会截断指针)," f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", "TypeError") return None - # _is_list_builtin_receiver - test list builtin methods from the receiver's actual type. + # _is_list_builtin_receiver - test list builtin methods from the receiver's actual type. # Prefer the actual LLVM struct name (sha1 stripped); fall back to the annotation/registered name. def _is_list_builtin_receiver(self, pool: memhub.MemBuddy*, recv_val: mlirlite.Value*, fallback_name: str, method_name: str, cl: ast.Call*) -> int: """Test list builtin methods from the receiver's actual type (fall back to the annotation name if unavailable)""" diff --git a/App/lib/core/Gen/Expr/ExprGenAttr.vp b/App/lib/core/Gen/Expr/ExprGenAttr.vp index 6912ee6..f26d23d 100644 --- a/App/lib/core/Gen/Expr/ExprGenAttr.vp +++ b/App/lib/core/Gen/Expr/ExprGenAttr.vp @@ -198,7 +198,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): # these objects are referenced at runtime, so emit a linkonce_odr definition with null init. is_t_type_obj: int = 0 if string.strcmp(mod_path_w, "t") == 0: is_t_type_obj = self._is_t_type_object_name(at.attr) - # a class name is not a module-level global: registered classes/structs/REnums are always + # a class name is not a module-level global: registered classes/structs/REnums are always # handled by the class/REnum paths, never manufactured into an external global here. if is_t_type_obj == 0 and self.Gen.StructGen.find_struct(at.attr) is not None: return None # fallback declaration name: t type objects (t.py uncompiled, no sha1) keep the bare @@ -600,7 +600,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): if alias_fe is not None and alias_fe.Ty is not None: alias_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, struct_ty, alias_fe.Ty, obj_ptr, alias_idx) if alias_ptr is not None: - # REnum variant field read by its declared type (matching match binding): the slot is i32/i64, + # REnum variant field read by its declared type (matching match binding): the slot is i32/i64, # so bitcast the slot address then load the declared type (no info loss) to avoid an int→ptr error. decl_ty_rn: mlirlite.LLVMType* = self.Gen.ClassGenEnum._lookup_renum_field_alias_ty(renum_se.Name, at.attr) if decl_ty_rn is not None: @@ -878,11 +878,9 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase): if bare is None: return None st: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(bare) if st is None: return None - fi: int = 0 - while fi < st.FieldCount: + for fi in range(st.FieldCount): fe_u: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(st, fi) if fe_u is not None and fe_u.Name is not None and string.strcmp(fe_u.Name, at.attr) == 0: return fe_u - fi += 1 return None def attr_field_pointee_is_volatile(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*) -> int: diff --git a/App/lib/core/Gen/Expr/ExprGenCdef.vp b/App/lib/core/Gen/Expr/ExprGenCdef.vp index 4fb8fdc..e1a264b 100644 --- a/App/lib/core/Gen/Expr/ExprGenCdef.vp +++ b/App/lib/core/Gen/Expr/ExprGenCdef.vp @@ -22,7 +22,7 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): """Cross-module CDefine lookup""" - # _build_source_path_from_sha1: build a source .vp/.py path from SHA1 via the StubMerger + # _build_source_path_from_sha1: build a source .vp/.py path from SHA1 via the StubMerger # global store (.vpi missing -> source .py); "lib/..." -> SourceDir, else IncludesDir. def _build_source_path_from_sha1(self, sha1: str) -> str: """Build a source .py path from a SHA1 via the global store""" @@ -49,7 +49,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): ridx: sizet = sizet(idx_s) * MAX_RPL rel_path: str = rel_arr_ptr + ridx if rel_path[0] == '\0': return None - # choose base dir: 1) stored includes root IncDir (absolute, supports multiple dirs); + # choose base dir: 1) stored includes root IncDir (absolute, supports multiple dirs); # 2) prefix heuristic: "lib/" -> SourceDir, "includes/" -> IncludesDir, else SourceDir then IncludesDir. base_dir: str = None rel_used: str = rel_path @@ -175,19 +175,15 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): if im_nlen > 0 and im_nlen < 256: im_buf: str = pool.alloc(im_nlen + 1) if im_buf is not None: - mk: sizet = 0 - while mk < im_nlen: + for mk in range(im_nlen): im_buf[mk] = imported_modules[im_start + mk] - mk += 1 im_buf[im_nlen] = '\0' sub_fi: str = pool.alloc(im_nlen + 3) if sub_fi is not None: sub_fi[0] = '*' sub_fi[1] = ':' - mk2: sizet = 0 - while mk2 < im_nlen: + for mk2 in range(im_nlen): sub_fi[2 + mk2] = im_buf[mk2] - mk2 += 1 sub_fi[2 + im_nlen] = '\0' sub_val: int64 = self._lookup_cross_module_cdefine(pool, name, sub_fi, None, depth + 1, node) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: return sub_val @@ -752,19 +748,15 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): if im2_nlen > 0 and im2_nlen < 256: im2_buf: str = pool.alloc(im2_nlen + 1) if im2_buf is not None: - mk3: sizet = 0 - while mk3 < im2_nlen: + for mk3 in range(im2_nlen): im2_buf[mk3] = imported_modules[im2_start + mk3] - mk3 += 1 im2_buf[im2_nlen] = '\0' sub_fi2: str = pool.alloc(im2_nlen + 3) if sub_fi2 is not None: sub_fi2[0] = '*' sub_fi2[1] = ':' - mk4: sizet = 0 - while mk4 < im2_nlen: + for mk4 in range(im2_nlen): sub_fi2[2 + mk4] = im2_buf[mk4] - mk4 += 1 sub_fi2[2 + im2_nlen] = '\0' sub_val2: int64 = self._lookup_cross_module_cdefine(pool, name, sub_fi2, None, depth + 1, node) if self.Gen.TypeGenCDef.is_cdefine_found() != 0: diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index 5e5f8ea..88cbd55 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -219,8 +219,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): if bare_u is not None: st_u: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(bare_u) if st_u is not None: - fi_u: int = 0 - while fi_u < st_u.FieldCount: + for fi_u in range(st_u.FieldCount): fe_u: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(st_u, fi_u) if fe_u is not None and fe_u.Name is not None and string.strcmp(fe_u.Name, at_u.attr) == 0: # [S4 read] An explicit unsigned field Spec wins @@ -229,7 +228,6 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): if fcn_u is not None: if self._annot_str_unsigned(fcn_u) != 0: return 1 break - fi_u += 1 return 0 return 0 def _node_type_signed(self, pool: memhub.MemBuddy*, node: ast.AST*, trans: HT.Translator* = None) -> int: diff --git a/App/lib/core/Gen/ImportsGenMixin.vp b/App/lib/core/Gen/ImportsGenMixin.vp index 45560d8..7e02136 100644 --- a/App/lib/core/Gen/ImportsGenMixin.vp +++ b/App/lib/core/Gen/ImportsGenMixin.vp @@ -179,8 +179,7 @@ novirtual class ImportsGenMixin: if name is None: return 0 if StubMergerStore.LookupSha1ByModName(name) is None: return 0 nl: sizet = string.strlen(name) - dot_pos: sizet = 0 - while dot_pos < nl: + for dot_pos in range(nl): if name[dot_pos] == '.': pfx: str = stdlib.malloc(dot_pos + 1) if pfx is not None: @@ -189,7 +188,6 @@ novirtual class ImportsGenMixin: hit: int = self.is_module_imported(imported_modules, pfx) stdlib.free(pfx) if hit != 0: return 1 - dot_pos += 1 return 0 # Add a from-import name mapping @@ -240,12 +238,10 @@ novirtual class ImportsGenMixin: # Compare the name if entry_name_len == name_len: Matched: int = 1 - ei: sizet = 0 - while ei < name_len: + for ei in range(name_len): if cur[ci + ei] != local_name[ei]: Matched = 0 break - ei += 1 if Matched == 1: # Match found; check for a third field (the original name) pos: sizet = colon1 + 1 @@ -309,12 +305,10 @@ novirtual class ImportsGenMixin: # Compare the name elif entry_name_len == name_len: Matched: int = 1 - ei: sizet = 0 - while ei < name_len: + for ei in range(name_len): if cur[ci + ei] != name[ei]: Matched = 0 break - ei += 1 if Matched == 1: mod_start2: sizet = colon_pos + 1 mod_end2: sizet = mod_start2 @@ -395,12 +389,10 @@ novirtual class ImportsGenMixin: pkg_len: sizet = string.strlen(pkg) last_dot: sizet = 0 found: int = 0 - i: sizet = 0 - while i < pkg_len: + for i in range(pkg_len): if pkg[i] == '.': last_dot = i found = 1 - i += 1 if found == 0: # No more parents (the relative level exceeds the package depth): fall back to # the original module; a later import SHA1 check reports "module not found". @@ -443,13 +435,11 @@ novirtual class ImportsGenMixin: # Find the last / or \ last_sep: sizet = 0 found: int = 0 - i: sizet = 0 - while i < rlen: + for i in range(rlen): ch: char = rel_path[i] if ch == '/' or ch == '\\': last_sep = i found = 1 - i += 1 if found == 0: # No directory separator -> top-level file, no package return None @@ -457,12 +447,10 @@ novirtual class ImportsGenMixin: dir_len: sizet = last_sep buf: str = pool.alloc(dir_len + 1) if buf is None: return None - j: sizet = 0 - while j < dir_len: + for j in range(dir_len): ch2: char = rel_path[j] if ch2 == '/' or ch2 == '\\': buf[j] = '.' else: buf[j] = ch2 - j += 1 buf[dir_len] = '\0' return buf diff --git a/App/lib/core/Gen/StructGenMixin.vp b/App/lib/core/Gen/StructGenMixin.vp index d3200b0..560da89 100644 --- a/App/lib/core/Gen/StructGenMixin.vp +++ b/App/lib/core/Gen/StructGenMixin.vp @@ -55,12 +55,10 @@ def _struct_ty_hash(tyval: uint64) -> uint64: """Hash a Ty pointer value with 32-bit FNV-1a over its 8 bytes.""" h: uint64 = uint64(FNV32_OFFSET) v: uint64 = tyval - j: int = 0 - while j < 8: + for j in range(8): h = (h ^ (v & uint64(255))) * uint64(FNV32_PRIME) h = h & uint64(FNV32_MASK) v = v >> 8 - j += 1 return h @@ -331,14 +329,12 @@ novirtual class StructGenMixin: h: uint64 = _struct_name_hash(name) mask: sizet = sizet(self.StructIdxCap - 1) idx: sizet = sizet(h) & mask - i: int = 0 - while i < self.StructIdxCap: + for i in range(self.StructIdxCap): slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8)) if slot[0] == 0: slot[0] = sizet(ei + 1) return 0 idx = (idx + 1) & mask - i += 1 return 1 def _struct_type_idx_insert(self, ei: int, tyval: uint64) -> int: @@ -348,14 +344,12 @@ novirtual class StructGenMixin: h: uint64 = _struct_ty_hash(tyval) mask: sizet = sizet(self.StructIdxCap - 1) idx: sizet = sizet(h) & mask - i: int = 0 - while i < self.StructIdxCap: + for i in range(self.StructIdxCap): slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8)) if slot[0] == 0: slot[0] = sizet(ei + 1) return 0 idx = (idx + 1) & mask - i += 1 return 1 def _struct_idx_add(self, ei: int, entry: GenTypes.StructEntry*) -> None: diff --git a/App/lib/core/Gen/Translator.vp b/App/lib/core/Gen/Translator.vp index 890755c..1705f7c 100644 --- a/App/lib/core/Gen/Translator.vp +++ b/App/lib/core/Gen/Translator.vp @@ -529,11 +529,9 @@ novirtual class Translator: """Return 1 if name is a registered Project macro variable.""" if name is None or proj_vars is None: return 0 n: sizet = len(proj_vars) - i: sizet = 0 - while i < n: + for i in range(n): s: str = proj_vars.get(i) if s is not None and string.strcmp(s, name) == 0: return 1 - i += 1 return 0 def _vb_is_project_ctor(self, value: ast.AST*, alias: str, ctor: str) -> int: @@ -631,26 +629,22 @@ novirtual class Translator: if kd == ast.ASTKind.Import: names: list[ast.AST*]* = ast.Import*(child).names if names is not None: - ni: sizet = 0 - while ni < len(names): + for ni in range(len(names)): al: ast.Alias* = ast.Alias*(names.get(ni)) if al is not None and al.name is not None: if string.strcmp(al.name, "viperbuild") == 0: if al.asname is not None: alias = al.asname else: alias = "viperbuild" - ni += 1 elif kd == ast.ASTKind.ImportFrom: ifr: ast.ImportFrom* = ast.ImportFrom*(child) if ifr is not None and ifr.level == 0 and ifr.names is not None: if ifr.module is not None and string.strcmp(ifr.module, "viperbuild") == 0: - ni: sizet = 0 - while ni < len(ifr.names): + for ni in range(len(ifr.names)): al: ast.Alias* = ast.Alias*(ifr.names.get(ni)) if al is not None and al.name is not None: if string.strcmp(al.name, "Project") == 0: if al.asname is not None: ctor = al.asname else: ctor = "Project" - ni += 1 ci += 1 if alias is None and ctor is None: return 0 # (2) Filter: register Project macro variables, then drop the related statements @@ -658,13 +652,11 @@ novirtual class Translator: kept: list[ast.AST*]* = list[ast.AST*](pool, 8) if proj_vars is None or kept is None: return 0 erased: int = 0 - ci = 0 - while ci < cn: + for ci in range(cn): child = ch.get(ci) if child is not None: if self._vb_is_macro_stmt(child, alias, ctor, proj_vars) != 0: erased = 1 else: kept.append(child) - ci += 1 if erased != 0: tree.children = kept return erased diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 690f3cc..753f41f 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -185,8 +185,7 @@ novirtual class TranslatorGenMixin: elem_ty_str_n: str = pool.alloc(512) if elem_ty_str_n is None: return None mlirlite.TypePrint(elem_ty_str_n, 512, elem_ty, pool) - i_n: sizet = 0 - while i_n < cnt_total_n: + for i_n in range(cnt_total_n): sub_n: str = None if i_n < elts_count: en_n: ast.AST* = elts.get(i_n) @@ -206,7 +205,6 @@ novirtual class TranslatorGenMixin: pos_n += sizet(written_n) written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n) pos_n += sizet(written_n) - i_n += 1 viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "]") return buf_n for zi in range(elts_count): @@ -238,8 +236,7 @@ novirtual class TranslatorGenMixin: # Write elements up to the declared length arr_count, zero-padding short lists so the # initializer element count always matches the type llc expects. - i: sizet = 0 - while i < cnt_total: + for i in range(cnt_total): elem_val: int64 = 0 if i < elts_count: elem_node: ast.AST* = elts.get(i) @@ -263,7 +260,6 @@ novirtual class TranslatorGenMixin: pos += sizet(written) written = viperlib.snprintf(buf + pos, buf_size - pos, "%s %lld", elem_ir_ty, elem_val) pos += sizet(written) - i += 1 # Write the closing "]" suffix viperlib.snprintf(buf + pos, buf_size - pos, "]") @@ -286,8 +282,7 @@ novirtual class TranslatorGenMixin: if buf is None: return None written: int = viperlib.snprintf(buf, buf_size, "[") pos: sizet = sizet(written) - i: sizet = 0 - while i < sizet(arr_count): + for i in range(sizet(arr_count)): if i > 0: written = viperlib.snprintf(buf + pos, buf_size - pos, ", ") pos += sizet(written) @@ -295,7 +290,6 @@ novirtual class TranslatorGenMixin: if i < slen: bv = int64(str_val[i]) written = viperlib.snprintf(buf + pos, buf_size - pos, "i8 %lld", bv) pos += sizet(written) - i += 1 viperlib.snprintf(buf + pos, buf_size - pos, "]") return buf diff --git a/App/lib/core/Gen/Type/TypeGenCDef.vp b/App/lib/core/Gen/Type/TypeGenCDef.vp index 9f70dbd..3bbd48d 100644 --- a/App/lib/core/Gen/Type/TypeGenCDef.vp +++ b/App/lib/core/Gen/Type/TypeGenCDef.vp @@ -64,8 +64,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase): h: uint64 = self._cdef_idx_hash(name) mask: sizet = sizet(self.CDefineNameIdxCap - 1) si: sizet = sizet(h) & mask - i: int = 0 - while i < self.CDefineNameIdxCap: + for i in range(self.CDefineNameIdxCap): slot: sizet* = self._cdef_idx_slot(si) sv: sizet = slot[0] if sv == 0: return -1 @@ -73,7 +72,6 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase): nm: str = self.CDefineNames.get(sizet(se)) if nm is not None and string.strcmp(nm, name) == 0: return se si = (si + 1) & mask - i += 1 return -1 def _cdef_idx_insert(self, slot_index: int, name: str) -> int: @@ -82,14 +80,12 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase): h: uint64 = self._cdef_idx_hash(name) mask: sizet = sizet(self.CDefineNameIdxCap - 1) si: sizet = sizet(h) & mask - i: int = 0 - while i < self.CDefineNameIdxCap: + for i in range(self.CDefineNameIdxCap): slot: sizet* = self._cdef_idx_slot(si) if slot[0] == 0: slot[0] = sizet(slot_index + 1) return 0 si = (si + 1) & mask - i += 1 return 1 def _cdef_idx_sync_append(self, name: str) -> None: diff --git a/App/lib/core/Gen/Type/TypeGenCType.vp b/App/lib/core/Gen/Type/TypeGenCType.vp index e632907..c0ed9ff 100644 --- a/App/lib/core/Gen/Type/TypeGenCType.vp +++ b/App/lib/core/Gen/Type/TypeGenCType.vp @@ -71,8 +71,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase): h: uint64 = _ctypedef_idx_hash(name) mask: sizet = sizet(self.CTypedefNameIdxCap - 1) si: sizet = sizet(h) & mask - i: int = 0 - while i < self.CTypedefNameIdxCap: + for i in range(self.CTypedefNameIdxCap): slot: sizet* = self._ctypedef_idx_slot(si) sv: sizet = slot[0] if sv == 0: return -1 @@ -80,7 +79,6 @@ class TypeGenCType(TypeGenBase.TypeGenBase): nm: str = self.CTypedefNames.get(sizet(se)) if nm is not None and string.strcmp(nm, name) == 0: return se si = (si + 1) & mask - i += 1 return -1 def _ctypedef_idx_insert(self, slot_index: int, name: str) -> int: @@ -89,14 +87,12 @@ class TypeGenCType(TypeGenBase.TypeGenBase): h: uint64 = _ctypedef_idx_hash(name) mask: sizet = sizet(self.CTypedefNameIdxCap - 1) si: sizet = sizet(h) & mask - i: int = 0 - while i < self.CTypedefNameIdxCap: + for i in range(self.CTypedefNameIdxCap): slot: sizet* = self._ctypedef_idx_slot(si) if slot[0] == 0: slot[0] = sizet(slot_index + 1) return 0 si = (si + 1) & mask - i += 1 return 1 def _ctypedef_idx_sync_append(self, name: str) -> None: @@ -216,12 +212,10 @@ class TypeGenCType(TypeGenBase.TypeGenBase): # rules out a match without strlen. if nm[0] != text[start] or string.strlen(nm) != want: continue hit: int = 1 - k: sizet = 0 - while k < want: + for k in range(want): if nm[k] != text[start + k]: hit = 0 break - k += 1 if hit != 0: ts: str = self.CTypedefTypeStrs.get(i) self.CTypedefFound = 1 diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index a8cc4c8..459f63c 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -331,15 +331,13 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if seg_len == 0: return type_name pipe_idx: sizet = seg_len p_depth: int = 0 - pi: sizet = 0 - while pi < seg_len: + for pi in range(seg_len): ch_p: int = type_name[pi] if ch_p == '[': p_depth += 1 elif ch_p == ']': p_depth -= 1 elif ch_p == '|' and p_depth == 0: pipe_idx = pi break - pi += 1 if pipe_idx < seg_len: left_buf: str = pool.alloc(pipe_idx + 1) if left_buf is None: return type_name @@ -376,15 +374,13 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # normalize each; t.CArray / list keep their count arg verbatim. lb_idx: sizet = seg_len ld: int = 0 - li2: sizet = 0 - while li2 < seg_len: + for li2 in range(seg_len): if type_name[li2] == '[': if ld == 0: lb_idx = li2 break ld += 1 elif type_name[li2] == ']': ld -= 1 - li2 += 1 if lb_idx < seg_len and type_name[seg_len - 1] == ']': container_g: str = pool.alloc(lb_idx + 1) if container_g is not None: @@ -675,12 +671,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # Check for '|' (BinOp): search only within the valid range [0, seg_len) pipe_idx: sizet = seg_len - pi: sizet = 0 - while pi < seg_len: + for pi in range(seg_len): if type_str[pi] == '|': pipe_idx = pi break - pi += 1 if pipe_idx < seg_len: # Copy the left segment into its own buffer (trim trailing spaces), preserving the original left_len: sizet = pipe_idx @@ -699,12 +693,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # Check for '[' (Subscript) like t.Callable[[int], int]; must precede the '.' # check since it is a Subscript. Parse fully via ast.parse_expression. bracket_idx: sizet = seg_len - bi: sizet = 0 - while bi < seg_len: + for bi in range(seg_len): if type_str[bi] == '[': bracket_idx = bi break - bi += 1 if bracket_idx < seg_len: # If the inner part starts with a digit (a "{16hex}.Class" name), the lexer # mis-scans it as a number; split base+slice manually for a single non-nested arg. @@ -759,12 +751,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): # Whether the text contains '.' (Attribute): search only within [0, seg_len). dot_idx: sizet = seg_len - di: sizet = 0 - while di < seg_len: + for di in range(seg_len): if type_str[di] == '.': dot_idx = di break - di += 1 if dot_idx < seg_len: # Trim trailing spaces of the module-name segment mod_len: sizet = dot_idx @@ -840,17 +830,17 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): lib_ty: mlirlite.LLVMType* = self.resolve_annotation_type(pool, lib_node, imported_modules, from_imports, trans, 1) self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 if lib_ty is not None: return lib_ty - # Bare Python/C builtin aliases: map_t_type only knows the t.CXxx spelling, so - # resolve them here to match resolve_annotation_type's bare-name branch. Without - # this the two-arg form int(x, t.CPtr) misses _tc_h4 and fails fast as "int". - if string.strcmp(name, "str") == 0: return mlirlite.Ptr(pool, mlirlite.Int8(pool)) - if string.strcmp(name, "bytes") == 0: return mlirlite.Ptr(pool, mlirlite.Int8(pool)) - if string.strcmp(name, "int") == 0: return mlirlite.Int32(pool) - if string.strcmp(name, "char") == 0: return mlirlite.Int8(pool) - if string.strcmp(name, "bool") == 0: return mlirlite.Int1(pool) - if string.strcmp(name, "float") == 0: return mlirlite.Float(pool) - if string.strcmp(name, "double") == 0: return mlirlite.Double(pool) - if string.strcmp(name, "void") == 0: return mlirlite.Void(pool) + # Bare Python/C builtin aliases: map_t_type only knows the t.CXxx spelling, so + # resolve them here to match resolve_annotation_type's bare-name branch. Without + # this the two-arg form int(x, t.CPtr) misses _tc_h4 and fails fast as "int". + if string.strcmp(name, "str") == 0: return mlirlite.Ptr(pool, mlirlite.Int8(pool)) + if string.strcmp(name, "bytes") == 0: return mlirlite.Ptr(pool, mlirlite.Int8(pool)) + if string.strcmp(name, "int") == 0: return mlirlite.Int32(pool) + if string.strcmp(name, "char") == 0: return mlirlite.Int8(pool) + if string.strcmp(name, "bool") == 0: return mlirlite.Int1(pool) + if string.strcmp(name, "float") == 0: return mlirlite.Float(pool) + if string.strcmp(name, "double") == 0: return mlirlite.Double(pool) + if string.strcmp(name, "void") == 0: return mlirlite.Void(pool) return self.map_t_type(pool, name) def get_type_size_bytes(self, pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str) -> int: """Return the type size in bytes via resolve_typedef_or_map, or 0 on failure.""" @@ -990,10 +980,8 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): out_buf[ci] = buf[line_start + name_s + ci] ci += 1 out_buf[name_l] = '\0' - ci = 0 - while ci < vlen: + for ci in range(vlen): out_buf[name_l + 1 + ci] = buf[line_start + vs + ci] - ci += 1 out_buf[name_l + 1 + vlen] = '\0' return 1 def _lookup_builtins_typedef(self, pool: memhub.MemBuddy*, name: str) -> str: @@ -2384,10 +2372,8 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): cur_lvl = nxt_lvl # Result = wrap the other side's type in N layers of Ptr res_ty: mlirlite.LLVMType* = cptr_other_ty - li2: int = 0 - while li2 < cptr_level: + for li2 in range(cptr_level): res_ty = mlirlite.Ptr(pool, res_ty) - li2 += 1 return res_ty # No CPtr marker: return the first non-attribute-marker side. Attribute markers diff --git a/App/lib/core/Gen/Type/TypeSpec.vp b/App/lib/core/Gen/Type/TypeSpec.vp index 4f75e52..d1608d9 100644 --- a/App/lib/core/Gen/Type/TypeSpec.vp +++ b/App/lib/core/Gen/Type/TypeSpec.vp @@ -185,8 +185,7 @@ def _spec_index_find(arena: TypeSpecArena*, key: str, h: uint64) -> int: if arena.Index is None or arena.IndexCap <= 0: return -1 mask: sizet = sizet(arena.IndexCap - 1) idx: sizet = sizet(h) & mask - i: int = 0 - while i < arena.IndexCap: + for i in range(arena.IndexCap): slot: sizet* = (sizet*)(uint64(arena.Index) + uint64(idx * 8)) sv: sizet = slot[0] if sv == 0: return -1 @@ -194,7 +193,6 @@ def _spec_index_find(arena: TypeSpecArena*, key: str, h: uint64) -> int: ek: str = _spec_key_at(arena.Keys, ei) if ek is not None and string.strcmp(ek, key) == 0: return ei idx = (idx + 1) & mask - i += 1 return -1 @@ -205,14 +203,12 @@ def _spec_index_insert(arena: TypeSpecArena*, key: str, h: uint64, ei: int) -> i if arena.Index is None or arena.IndexCap <= 0: return 1 mask: sizet = sizet(arena.IndexCap - 1) idx: sizet = sizet(h) & mask - i: int = 0 - while i < arena.IndexCap: + for i in range(arena.IndexCap): slot: sizet* = (sizet*)(uint64(arena.Index) + uint64(idx * 8)) if slot[0] == 0: slot[0] = sizet(ei + 1) return 0 idx = (idx + 1) & mask - i += 1 return 1 @@ -426,8 +422,7 @@ def _spec_to_text(sp: TypeSpec*, buf: str, buf_size: sizet, depth: int) -> int: pos: sizet = 0 pos = _spec_text_append(buf, buf_size, pos, "fn(") if pos >= buf_size: return 1 - i: int = 0 - while i < sp.ParamCount: + for i in range(sp.ParamCount): if i > 0: pos = _spec_text_append(buf, buf_size, pos, ",") if pos >= buf_size: return 1 @@ -438,7 +433,6 @@ def _spec_to_text(sp: TypeSpec*, buf: str, buf_size: sizet, depth: int) -> int: if _spec_to_text(param, param_buf, SPEC_TEXT_MAX, depth + 1) != 0: return 1 pos = _spec_text_append(buf, buf_size, pos, param_buf) if pos >= buf_size: return 1 - i += 1 if sp.IsVarArg == 1: if sp.ParamCount > 0: pos = _spec_text_append(buf, buf_size, pos, ",...") else: pos = _spec_text_append(buf, buf_size, pos, "...") @@ -461,14 +455,12 @@ def _spec_text_append(buf: str, buf_size: sizet, pos: sizet, text: str) -> sizet """Append text at pos in buf; buf_size sentinel when full, else the new position""" if buf is None or text is None: return buf_size tlen: sizet = string.strlen(text) - i: sizet = 0 - while i < tlen: + for i in range(tlen): if pos + 1 >= buf_size: buf[pos] = '\0' return buf_size buf[pos] = text[i] pos += 1 - i += 1 buf[pos] = '\0' return pos @@ -626,14 +618,12 @@ def InternSpec(arena: TypeSpecArena*, sp: TypeSpec*) -> TypeSpec*: return (TypeSpec*)(uint64(slot_e[0])) if arena.Index is None: # index unavailable: fall back to the linear scan - i: int = 0 - while i < arena.Count: + for i in range(arena.Count): exist_key: str = _spec_key_at(arena.Keys, i) if exist_key is not None and string.strcmp(exist_key, key_buf) == 0: slot_e2: sizet* = (sizet*)(uint64(arena.Specs) + uint64(i * 8)) if slot_e2 is None: return None return (TypeSpec*)(uint64(slot_e2[0])) - i += 1 # Miss: append. Table full = fail-fast (never return None, which would silently # lose type info up the call chain and corrupt signedness -> zext/sext direction). if arena.Count >= arena.Cap: @@ -881,14 +871,12 @@ def _spec_llvm_text(sp: TypeSpec*, buf: str, buf_size: sizet, depth: int) -> int if sp.Kind == TS_FUNC: if _spec_llvm_text(sp.Ret, buf, buf_size, depth + 1) != 0: return 1 if _spec_llvm_append(buf, buf_size, " (") != 0: return 1 - i: int = 0 - while i < sp.ParamCount: + for i in range(sp.ParamCount): if i > 0: if _spec_llvm_append(buf, buf_size, ", ") != 0: return 1 ps: TypeSpec* = _spec_param_at(sp, i) if ps is None: return 1 if _spec_llvm_text(ps, buf, buf_size, depth + 1) != 0: return 1 - i += 1 # vararg suffix (unique to this Spec convention, see above) if sp.IsVarArg == 1: if sp.ParamCount > 0: diff --git a/App/lib/core/Repl.vp b/App/lib/core/Repl.vp index 9ca0d00..a6bca32 100644 --- a/App/lib/core/Repl.vp +++ b/App/lib/core/Repl.vp @@ -1377,11 +1377,9 @@ def _repl_sig_to_text(tag: int, bits: int, pc: int) -> str: """Render ReplSigResult + ReplSigTags/Bits as "(P1, P2) -> R" (PermPool buffer).""" if ReplSigText is None: return "(?)" pos: int = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, 0, "(") - i: int = 0 - while i < pc: + for i in range(pc): if i > 0: pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, ", ") pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(int(ReplSigTags[i]), int(ReplSigBits[i]))) - i += 1 pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, ") -> ") pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(tag, bits)) if pos < 0: return "(?)" @@ -1428,12 +1426,10 @@ def _repl_precheck_session_funcs(mod: mlirlite.LLVMModule*) -> int: sig_same: int = 1 if old.RetTag != ReplSigResult.RetTag or old.RetBits != ReplSigResult.RetBits or old.ParamCount != ReplSigResult.ParamCount: sig_same = 0 if sig_same != 0: - pi: int = 0 - while pi < old.ParamCount: + for pi in range(old.ParamCount): if int(old.ParamTags[pi]) != int(ReplSigTags[pi]) or int(old.ParamBits[pi]) != int(ReplSigBits[pi]): sig_same = 0 break - pi += 1 if sig_same == 0: stdio.printf("M3: 会话函数 '%s' 重定义签名不一致(旧 %s,新 %s)\n" " M3 允许同签名覆盖(只换地址);换签名会让先前片段里已编好的" "调用点按旧 ABI 调新代码 —— 该片段整体不执行,请换名字\n", nm, _repl_entry_sig_text(old), _repl_sig_to_text(ReplSigResult.RetTag, ReplSigResult.RetBits, ReplSigResult.ParamCount)) return 1 @@ -1447,11 +1443,9 @@ def _repl_precheck_session_funcs(mod: mlirlite.LLVMModule*) -> int: def _repl_entry_sig_text(e: rawptr[GenTypes.ReplFuncEntry]) -> str: if e is None or ReplSigText2 is None: return "(?)" pos: int = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, 0, "(") - i: int = 0 - while i < e.ParamCount: + for i in range(e.ParamCount): if i > 0: pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, ", ") pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(int(e.ParamTags[i]), int(e.ParamBits[i]))) - i += 1 pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, ") -> ") pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(e.RetTag, e.RetBits)) if pos < 0: return "(?)" diff --git a/App/lib/core/builtin/ViperBuild.vp b/App/lib/core/builtin/ViperBuild.vp index 579d8df..e853cc6 100644 --- a/App/lib/core/builtin/ViperBuild.vp +++ b/App/lib/core/builtin/ViperBuild.vp @@ -131,11 +131,9 @@ def _BaseNameOf(path: str) -> str: if path is None: return None n: sizet = string.strlen(path) start: sizet = 0 - i: sizet = 0 - while i < n: + for i in range(n): ch: char = path[i] if ch == '/' or ch == '\\': start = i + 1 - i += 1 return _DupStd(path + start) @@ -168,12 +166,10 @@ def _FindInList(names: list[str]*, name: str) -> int: """Linear-search names for name; return its index, or -1 if not found.""" if names is None or name is None: return -1 n: sizet = names.__len__() - i: sizet = 0 - while i < n: + for i in range(n): s: str = names.get(i) if s is not None: if string.strcmp(s, name) == 0: return int(i) - i += 1 return -1 @@ -203,8 +199,7 @@ def _SplitInto(out: list[str]*, joined: str) -> int: n: sizet = string.strlen(joined) if n == 0: return 1 start: sizet = 0 - i: sizet = 0 - while i <= n: + for i in range(n + 1): if i == n or joined[i] == char(VB_SEP_CODE): seg: str = stdlib.malloc(i - start + 1) if seg is None: return 0 @@ -213,7 +208,6 @@ def _SplitInto(out: list[str]*, joined: str) -> int: out.append(_DupScratch(seg)) stdlib.free(seg) start = i + 1 - i += 1 return 1 @@ -233,8 +227,7 @@ def _JoinSep(lst: list[str]*) -> str: buf: str = _scratch.alloc(total + 1) if buf is None: return None pos: sizet = 0 - i = 0 - while i < n: + for i in range(n): s = lst.get(i) if s is not None: sl: sizet = string.strlen(s) @@ -243,7 +236,6 @@ def _JoinSep(lst: list[str]*) -> str: pos += 1 string.strcpy(buf + pos, s) pos += sl - i += 1 buf[pos] = '\0' return buf @@ -263,8 +255,7 @@ def _JoinSpace(lst: list[str]*) -> str: buf: str = stdlib.malloc(total + 1) if buf is None: return None pos: sizet = 0 - i = 0 - while i < n: + for i in range(n): s = lst.get(i) if s is not None: sl: sizet = string.strlen(s) @@ -273,7 +264,6 @@ def _JoinSpace(lst: list[str]*) -> str: pos += 1 string.strcpy(buf + pos, s) pos += sl - i += 1 buf[pos] = '\0' return buf @@ -284,12 +274,10 @@ def _FirstSpaceTok(joined: str) -> str: n: sizet = string.strlen(joined) if n == 0: return None sp: sizet = n - i: sizet = 0 - while i < n: + for i in range(n): if joined[i] == ' ': sp = i break - i += 1 seg: str = stdlib.malloc(sp + 1) if seg is None: return None string.strncpy(seg, joined, sp) @@ -349,8 +337,7 @@ def _EvalList(node: ast.AST*, out: list[str]*) -> int: lst: ast.List* = ast.List*(node) if lst is None or lst.elts is None: return 0 n: sizet = lst.elts.__len__() - i: sizet = 0 - while i < n: + for i in range(n): e: ast.AST* = lst.elts.get(i) if e is None: return 0 if e.kind() == ast.ASTKind.Starred: @@ -360,7 +347,6 @@ def _EvalList(node: ast.AST*, out: list[str]*) -> int: else: if _EvalStr(e) == 0: return 0 out.append(_DupScratch(_g_out_str)) - i += 1 return 1 if k == ast.ASTKind.BinOp: bop: ast.BinOp* = ast.BinOp*(node) @@ -423,8 +409,7 @@ def _HandleImport(stmt: ast.Import*) -> int: global _alias, _saw_viperbuild if stmt is None or stmt.names is None: return 0 n: sizet = stmt.names.__len__() - i: sizet = 0 - while i < n: + for i in range(n): al: ast.Alias* = ast.Alias*(stmt.names.get(i)) if al is not None and al.name is not None: if string.strcmp(al.name, "viperbuild") == 0: @@ -432,7 +417,6 @@ def _HandleImport(stmt: ast.Import*) -> int: if al.asname is not None: _alias = _DupScratch(al.asname) else: _alias = _DupScratch("viperbuild") else: _AddPending(al.name) - i += 1 return 0 @@ -450,14 +434,12 @@ def _HandleImportFrom(stmt: ast.ImportFrom*) -> int: _saw_viperbuild = 1 if stmt.names is None: return 0 n: sizet = stmt.names.__len__() - i: sizet = 0 - while i < n: + for i in range(n): al: ast.Alias* = ast.Alias*(stmt.names.get(i)) if al is not None and al.name is not None: if string.strcmp(al.name, "Project") == 0: if al.asname is not None: _ctor_name = _DupScratch(al.asname) else: _ctor_name = _DupScratch("Project") - i += 1 return 0 @@ -505,8 +487,7 @@ def _ApplyCtorArgs(cl: ast.Call*) -> int: _c_version = _DupStd(_g_out_str) if cl.keywords is None: return 0 n: sizet = cl.keywords.__len__() - i: sizet = 0 - while i < n: + for i in range(n): kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i)) if kw is not None and kw.arg is not None and kw.value is not None: if string.strcmp(kw.arg, "name") == 0: @@ -522,7 +503,6 @@ def _ApplyCtorArgs(cl: ast.Call*) -> int: else: VLogger.error(f"viperbuild: Project(...) 不支持的关键字 {kw.arg}", "viperbuild") return 1 - i += 1 return 0 @@ -660,12 +640,10 @@ def _HandleConfigCall(cl: ast.Call*) -> int: """Handle a proj.config(kw=...) call.""" if cl is None or cl.keywords is None: return 0 n: sizet = cl.keywords.__len__() - i: sizet = 0 - while i < n: + for i in range(n): kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i)) if kw is not None and kw.arg is not None and kw.value is not None: if _SetField(kw.arg, kw.value) != 0: return 1 - i += 1 return 0 @@ -679,8 +657,7 @@ def _HandleBuildCall(cl: ast.Call*) -> int: _c_has_build = 1 if cl.keywords is None: return 0 n: sizet = cl.keywords.__len__() - i: sizet = 0 - while i < n: + for i in range(n): kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i)) if kw is not None and kw.arg is not None and kw.value is not None: if string.strcmp(kw.arg, "triple") == 0: @@ -702,7 +679,6 @@ def _HandleBuildCall(cl: ast.Call*) -> int: else: VLogger.error(f"viperbuild: build(...) 不支持的关键字 {kw.arg}", "viperbuild") return 1 - i += 1 return 0 @@ -711,18 +687,14 @@ def _CallArgsHaveProjRef(cl: ast.Call*) -> int: if cl is None: return 0 if cl.args is not None: n: sizet = cl.args.__len__() - i: sizet = 0 - while i < n: + for i in range(n): if _IsProjRef(cl.args.get(i)) != 0: return 1 - i += 1 if cl.keywords is not None: n = cl.keywords.__len__() - i = 0 - while i < n: + for i in range(n): kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i)) if kw is not None and kw.value is not None: if _IsProjRef(kw.value) != 0: return 1 - i += 1 return 0 @@ -803,8 +775,7 @@ def _ScanFile(pool: memhub.MemBuddy*, path: str) -> int: rc: int = 0 if body is not None: cn: sizet = len(body) - ci: sizet = 0 - while ci < cn: + for ci in range(cn): child: ast.AST* = body.get(ci) if child is not None: kd: int = child.kind() @@ -814,7 +785,6 @@ def _ScanFile(pool: memhub.MemBuddy*, path: str) -> int: elif kd == ast.ASTKind.AnnAssign: rc = _HandleAnnAssign(ast.AnnAssign*(child)) elif kd == ast.ASTKind.Expr: rc = _HandleExprStmt(ast.Expr*(child)) if rc != 0: break - ci += 1 pool.reset_to(mark) stdlib.free(src_buf) @@ -883,13 +853,11 @@ def _RunBfs(pool: memhub.MemBuddy*, entry_path: str) -> int: if rc == 1: return 1 # Resolve module names collected from this file pn: sizet = _pending.__len__() - pi: sizet = 0 - while pi < pn: + for pi in range(pn): mod: str = _pending.get(pi) if mod is not None: dep: str = _ResolveModuleToFile(mod) if dep is not None: _Enqueue(dep) - pi += 1 return 0 @@ -939,10 +907,8 @@ def _ProbeIncludes() -> str: k: int = 0 while k <= 3: base: str = _DupStd(exe_dir) - j: int = 0 - while j < k: + for j in range(k): base = _Join2(base, "..") - j += 1 cand: str = _Join2(base, "includes") if _IsDir(cand) != 0: return cand k += 1 @@ -955,12 +921,10 @@ def _DeriveOutputFromEntry(entry_path: str) -> str: if base is None: return "app.exe" n: sizet = string.strlen(base) cut: sizet = n - i: sizet = 0 - while i < n: + for i in range(n): if base[i] == '.': cut = i break - i += 1 head: str = stdlib.malloc(cut + 5) if head is None: return "app.exe" string.strncpy(head, base, cut) @@ -1047,12 +1011,10 @@ def _SplitToolCmd(joined: str, which: int) -> None: if joined is None: return n: sizet = string.strlen(joined) sp: sizet = n - i: sizet = 0 - while i < n: + for i in range(n): if joined[i] == ' ': sp = i break - i += 1 cmd: str = stdlib.malloc(sp + 1) if cmd is not None: string.strncpy(cmd, joined, sp)