refactor(gen): R12 收尾同步——12 处计数 while 循环改 for range

与 includes 同步:<= 条件转 range(expr + 1),并放宽初始化行的紧贴要求(同块内最近一次写即为初始化即可)。其余保守守卫不变。

验证:bootstrap 三重重编 SUCCESS;全量 77/77 顺序回归通过。
This commit is contained in:
TermiNexus committed 2026-10-05 16:36:36 +08:00
1 parent fb53f88893
commit aeb4e8e54c
7 files changed
+12 -36

No files matched your search

+1 -3
View File
@@ -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:
+2 -6
View File
@@ -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).
+2 -6
View File
@@ -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*:
+1 -3
View File
@@ -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")
+1 -3
View File
@@ -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."""
+4 -12
View File
@@ -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 "<arg>*" 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)
+1 -3
View File
@@ -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