From aeb4e8e54c5ec90050d66e4a66fbb8d589872781 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 5 Oct 2026 16:36:36 +0800 Subject: [PATCH] =?UTF-8?q?refactor(gen):=20R12=20=E6=94=B6=E5=B0=BE?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E2=80=94=E2=80=9412=20=E5=A4=84=E8=AE=A1?= =?UTF-8?q?=E6=95=B0=20while=20=E5=BE=AA=E7=8E=AF=E6=94=B9=20for=20range?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与 includes 同步:<= 条件转 range(expr + 1),并放宽初始化行的紧贴要求(同块内最近一次写即为初始化即可)。其余保守守卫不变。 验证:bootstrap 三重重编 SUCCESS;全量 77/77 顺序回归通过。 --- App/lib/Projectrans/Config.vp | 4 +--- App/lib/core/Gen/Call/CallGenCall.vp | 8 ++------ App/lib/core/Gen/Class/ClassGenGeneric.vp | 8 ++------ App/lib/core/Gen/GenApi.vp | 4 +--- App/lib/core/Gen/Type/TypeGenCType.vp | 4 +--- App/lib/core/Gen/Type/TypeGenResolve.vp | 16 ++++------------ App/lib/core/builtin/ViperBuild.vp | 4 +--- 7 files changed, 12 insertions(+), 36 deletions(-) diff --git a/App/lib/Projectrans/Config.vp b/App/lib/Projectrans/Config.vp index dcb47fa..386ea2a 100644 --- a/App/lib/Projectrans/Config.vp +++ b/App/lib/Projectrans/Config.vp @@ -305,11 +305,9 @@ def _normalize_path(path: str) -> str: if has_seg > 0: out[out_len] = '/' out_len += 1 - jj: sizet = 0 - while jj < seg_len: + for jj in range(seg_len): out[out_len] = path[seg_start + jj] out_len += 1 - jj += 1 has_seg = 1 seg_start = i + 1 if has_seg == 0: diff --git a/App/lib/core/Gen/Call/CallGenCall.vp b/App/lib/core/Gen/Call/CallGenCall.vp index 8710c9e..e84648b 100644 --- a/App/lib/core/Gen/Call/CallGenCall.vp +++ b/App/lib/core/Gen/Call/CallGenCall.vp @@ -1553,9 +1553,8 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): """Is the receiver class a direct parent of any registered class; 1=yes / 0=no.""" if class_name is None: return 0 if self.Gen is None: return 0 - j: int = 0 n: int = self.Gen.StructGen.get_struct_count() - while j < n: + for j in range(n): 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) @@ -1563,7 +1562,6 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): 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 - j += 1 return 0 # _mixin_sibling_same_composite - do both classes share a composite class's MRO? @@ -1572,9 +1570,8 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): """Do both classes share a registered composite class's MRO; 1=yes / 0=no.""" if class_name is None or cand_name is None or pool is None: return 0 if self.Gen is None: return 0 - j: int = 0 n: int = self.Gen.StructGen.get_struct_count() - while j < n: + for j in range(n): k_entry: GenTypes.StructEntry* = self.Gen.StructGen._get_struct_entry(j) if k_entry is not None and k_entry.Name is not None: mro: sizet* = self.Gen.StructGen.get_mro_chain(pool, k_entry.Name) @@ -1589,7 +1586,6 @@ novirtual class CallGenCall(CallGenBase.CallGenBase): elif string.strcmp(nm, cand_name) == 0: has_cand = 1 if has_self != 0 and has_cand != 0: return 1 mi += 1 - j += 1 return 0 # _field_byte_offset - byte offset of a field in the struct layout (with padding). diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index 73b75b8..1e4674e 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -198,9 +198,8 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): tp_list: list[str]* = list[str](pool, 8) if tp_list is None: return None seg_start: sizet = 0 - pos: sizet = 0 blen: sizet = string.strlen(buf_tp) - while pos <= blen: + for pos in range(blen + 1): if buf_tp[pos] == ' ' or buf_tp[pos] == '\0': seg_len: sizet = pos - seg_start if seg_len > 0: @@ -210,7 +209,6 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): seg[seg_len] = '\0' tp_list.append(seg) seg_start = pos + 1 - pos += 1 return tp_list return None @@ -541,9 +539,8 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): tp_list: list[str]* = list[str](pool, 8) if tp_list is None: return None seg_start: sizet = 0 - pos: sizet = 0 blen: sizet = string.strlen(buf_tp) - while pos <= blen: + for pos in range(blen + 1): if buf_tp[pos] == ' ' or buf_tp[pos] == '\0': seg_len: sizet = pos - seg_start if seg_len > 0: @@ -553,7 +550,6 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): seg[seg_len] = '\0' tp_list.append(seg) seg_start = pos + 1 - pos += 1 return tp_list return None def _find_generic_template(self, class_name: str) -> ast.ClassDef*: diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index 7a2ad75..c5118fe 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -433,16 +433,14 @@ def fail_if_fstring_escape(node: ast.AST*, where: str) -> int: elif k == ast.ASTKind.Tuple: tp: ast.Tuple* = ast.Tuple*(node) if tp.elts is not None: - i: sizet = 0 en: sizet = len(tp.elts) - while i < en: + for i in range(en): e: ast.AST* = tp.elts.get(i) if e is not None: ek: int = e.kind() if ek == ast.ASTKind.JoinedStr or ek == ast.ASTKind.FormattedValue: hit = 1 break - i += 1 if hit == 0: return 0 if _g_gen is not None: _g_gen.TypeGenErr.fatal_error(node, f"f-string 结果不能用于{where}(逃逸):f-string 指向**当前函数的栈缓冲**," f"函数返回即失效,把这个指针带出函数会读到已弹栈的帧" f"(历史事故:ASan stack-buffer-underflow in vsnprintf)。" f"需要带出函数时显式分配后拷贝:" f"tmp: str = f\"...\";out: str = GenApi.escape_fstring_copy(tmp);return out。", "TypeError") diff --git a/App/lib/core/Gen/Type/TypeGenCType.vp b/App/lib/core/Gen/Type/TypeGenCType.vp index c0ed9ff..a0f90ef 100644 --- a/App/lib/core/Gen/Type/TypeGenCType.vp +++ b/App/lib/core/Gen/Type/TypeGenCType.vp @@ -419,10 +419,9 @@ class TypeGenCType(TypeGenBase.TypeGenBase): src_len: sizet = string.strlen(src) count: int = 0 line_start: sizet = 0 - i: sizet = 0 # line parse buffer ("NAME\0VALUE\0"), reused per file (register_ctypedef copies) td_buf: str = pool.alloc(320) - while i <= src_len: + for i in range(src_len + 1): if i == src_len or src[i] == '\n': line_len: sizet = i - line_start if line_len > 0 and td_buf is not None: @@ -434,7 +433,6 @@ class TypeGenCType(TypeGenBase.TypeGenBase): self.register_ctypedef(pool, name_buf, ty_buf) count += 1 line_start = i + 1 - i += 1 return count def _eval_const_int_expr(self, node: ast.AST*, pool: memhub.MemBuddy* = None, from_imports: str = None, imported_modules: str = None, depth: int = 0) -> int: """Recursively evaluate a constant integer expression with cross-module lookup.""" diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index 459f63c..fd501ad 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -406,12 +406,11 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): if arg_list_g is not None: arg_start_g: sizet = 0 cur_dep_g = 0 - ci_g = 0 # The second arg of a fixed-size container is an element count (CDefine # name / literal / const expr), not a type name, so keep it verbatim. _cntc_g: int = self._is_count_arg_container(container_g) _argi_g: int = 0 - while ci_g <= inner_len_g: + for ci_g in range(inner_len_g + 1): is_sep_g: int = 0 if ci_g < inner_len_g: if inner_buf_g[ci_g] == '[': cur_dep_g += 1 @@ -434,7 +433,6 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): else: arg_list_g.append(abuf_g) _argi_g += 1 arg_start_g = ci_g + 1 - ci_g += 1 # [pointer-marker container normalization] Single-arg `rawptr[T]` / # `t.CPtr[T]` / `CPtr[T]` yields "*" so it folds with `T*`. if self._is_ptr_subscript_container_text(container_g) != 0 and len(arg_list_g) == 1: @@ -1030,9 +1028,8 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): b_total: sizet = string.strlen(b_buf) # Pre-scan import lines to register aliases (import stdint as __stdint), so later # module-qualified typedef expansion can resolve the real module name. - b_imp_i: sizet = 0 b_imp_ls: sizet = 0 - while b_imp_i <= b_total: + for b_imp_i in range(b_total + 1): if b_imp_i == b_total or b_buf[b_imp_i] == '\n': b_imp_len: sizet = b_imp_i - b_imp_ls if b_imp_len > 0: @@ -1070,14 +1067,12 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): b_al_buf[b_al_e - b_al_s] = '\0' self._register_import_alias(b_al_buf, b_tgt_buf) b_imp_ls = b_imp_i + 1 - b_imp_i += 1 - b_i: sizet = 0 b_line_start: sizet = 0 b_res: str = None # Line parse buffer ("NAME\0VALUE\0") reused for the whole file; values to keep are # copied out (register_ctypedef copies internally; only b_res needs copying). b_td_buf: str = pool.alloc(320) - while b_i <= b_total: + for b_i in range(b_total + 1): if b_i == b_total or b_buf[b_i] == '\n': b_line_len: sizet = b_i - b_line_start if b_line_len > 0 and b_td_buf is not None: @@ -1100,7 +1095,6 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): b_res = pool.alloc(b_vl + 1) if b_res is not None: string.strcpy(b_res, b_tb) b_line_start = b_i + 1 - b_i += 1 # Mark scanning complete: later misses in this file query the table instead of re-reading self.Gen.TypeGenCType.BuiltinsTypedefScanned = 1 # b_res is already copied to pool; finish expansion/diagnostics before free(b_buf), @@ -1202,7 +1196,6 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): return None if m_read < LONG(BUF_L): m_buf[sizet(m_read)] = 0 m_total: sizet = string.strlen(m_buf) - m_i: sizet = 0 m_ls: sizet = 0 m_res: str = None # Line parse buffer ("NAME\0VALUE\0") reused for the whole file; hits are copied out @@ -1210,7 +1203,7 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): m_td_buf: str = pool.alloc(320) # Scan the whole file (no early exit) to build the full persistent cache and still # take attr's first-hit value with the same comparison as before. - while m_i <= m_total: + for m_i in range(m_total + 1): if m_i == m_total or m_buf[m_i] == '\n': m_line_len: sizet = m_i - m_ls if m_line_len > 0 and m_td_buf is not None: @@ -1228,7 +1221,6 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase): m_res = pool.alloc(m_vl + 1) if m_res is not None: string.strcpy(m_res, m_tb) m_ls = m_i + 1 - m_i += 1 # Mark the module scanned: later queries for it only use the persistent cache self._mark_lib_module_scanned(m_real) if m_res is not None: self.Gen.TypeGenCType.register_ctypedef(pool, attr, m_res) diff --git a/App/lib/core/builtin/ViperBuild.vp b/App/lib/core/builtin/ViperBuild.vp index e853cc6..7eb0b33 100644 --- a/App/lib/core/builtin/ViperBuild.vp +++ b/App/lib/core/builtin/ViperBuild.vp @@ -904,14 +904,12 @@ def _ProbeIncludes() -> str: exe_dir: str = _DirOf(exe_buf) stdlib.free(exe_buf) if exe_dir is None: return None - k: int = 0 - while k <= 3: + for k in range(3 + 1): base: str = _DupStd(exe_dir) for j in range(k): base = _Join2(base, "..") cand: str = _Join2(base, "includes") if _IsDir(cand) != 0: return cand - k += 1 return None