From 18d753999d0da95112719d749b4b613212a29a1b Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 10 Oct 2026 15:24:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(preprocess):=20ExpandSoftKeywords=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20new=20=E7=94=9F=E5=91=BD=E5=91=A8=E6=9C=9F?= =?UTF-8?q?=E8=BD=AF=E5=85=B3=E9=94=AE=E5=AD=97=E5=B1=95=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TPV 的 new [描述符...] T(args) 出现在共享 includes(w32/fileio.vp 的 return new File(...))后会打断 TPC 引导编译(TPC 把它当普通名字 → NameError)。新增第 10 种展开 _ExpandNewExprs:把 new + [stack|heap|hlife|slife|memgr(...)] + 类型名 + ( 删成等价裸构造 T(args),TPC 无需理解生命周期语义;new = 1 / new.x / new(1) / for new in 仍作标识符,跨行不处理。 --- lib/core/SymbolUtils.py | 83 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/lib/core/SymbolUtils.py b/lib/core/SymbolUtils.py index eb9cc8a..006148a 100644 --- a/lib/core/SymbolUtils.py +++ b/lib/core/SymbolUtils.py @@ -1614,6 +1614,10 @@ def ExpandSoftKeywords(Code: str) -> str: 后者由 vast.Parser._ParseStaticDef 处理)不受影响; `extern` 带初值**响亮失败**(外部定义不写初值)。 九种展开都同行替换(长度可增,不增删换行),AST 行号映射保持有效。 + 10) `new [描述符...] T(args)` → `T(args)`(见 _ExpandNewExprs):TPV 的生命周期 + 分配软关键字,TPC 不解其语义,展开成等价裸构造(TPC 的常规分配路径)即可; + 只有"new + [描述符] + 类型名 + (" 形态命中,`new = 1` / `new.x` / `new(1)` / + `for new in` 仍是标识符。 """ if not Code: return Code @@ -1627,9 +1631,88 @@ def ExpandSoftKeywords(Code: str) -> str: return Result +# --------------------------------------------------------------------------- +# `new` 生命周期表达式(TPV 软关键字)的 TPC 容忍层 +# --------------------------------------------------------------------------- +# TPV 用 `new [描述符...] T(args)`(见 includes/ast/parser.vp)表达"分配 + 生命周期"; +# 共享 includes(如 includes/w32/fileio.vp 的 `return new File(...)`)会带上它,但 TPC 不认 +# `new`(当普通名字 → NameError),于是 TPC 引导编译 TransPyV 时中断。 +# 本层把它展开成等价的裸构造 `T(args)`(TPC 的常规分配路径,与展开前 include 源码一致); +# 只认"new + [描述符] + 类型名 + (" 这一形态——`new = 1` / `new.x` / `new(1)` / `for new in` +# 仍是标识符(与 TPV parser 的软关键字判据同口径)。跨行 new 表达式不处理(保持原样, +# 由后续 parse 响亮失败)。 +_NEW_LIFE_DESCRIPTORS: frozenset[str] = frozenset({'stack', 'heap', 'hlife', 'slife'}) + + +def _ExpandNewExprs(Code: str) -> str: + """`new [stack|heap|hlife|slife|memgr(...)] T(args)` → `T(args)`(TPC 容忍展开)。 + + 仅命中"new + [描述符...] + 类型名 + '('"形态;其余 `new`(标识符)原样保留。 + 命中后删除 `[new .. 类型名)` 这一段(同行),保留类型名与其后的调用。 + """ + if 'new' not in Code: + return Code + try: + Tokens: list = list(tokenize.generate_tokens(io.StringIO(Code).readline)) + except Exception: + return Code + n: int = len(Tokens) + Lines0: list[str] = Code.splitlines() + Edits: list[tuple[int, int, int, str, str]] = [] + i: int = 0 + while i < n: + Tok = Tokens[i] + i += 1 + if Tok.type != tokenize.NAME or Tok.string != 'new': + continue + # 跳过描述符(顺序无关;memgr 带一个括号组) + j: int = _NextSignificantTokenIndex(Tokens, i - 1) + while j >= 0: + Tj = Tokens[j] + if Tj.type == tokenize.NAME and Tj.string in _NEW_LIFE_DESCRIPTORS: + j = _NextSignificantTokenIndex(Tokens, j) + continue + if Tj.type == tokenize.NAME and Tj.string == 'memgr': + k: int = _NextSignificantTokenIndex(Tokens, j) + if k >= 0 and Tokens[k].type == tokenize.OP and Tokens[k].string == '(': + depth: int = 0 + m: int = k + while m < n: + if Tokens[m].type == tokenize.OP and Tokens[m].string == '(': + depth += 1 + elif Tokens[m].type == tokenize.OP and Tokens[m].string == ')': + depth -= 1 + if depth == 0: + break + m += 1 + j = _NextSignificantTokenIndex(Tokens, m) if m < n else -1 + continue + break + if j < 0: + continue + TypeTok = Tokens[j] + # 类型名:NAME 且本身不是描述符(`new heap` 这种缺类型的不命中) + if TypeTok.type != tokenize.NAME or TypeTok.string in _NEW_LIFE_DESCRIPTORS: + continue + k2: int = _NextSignificantTokenIndex(Tokens, j) + if k2 < 0 or Tokens[k2].type != tokenize.OP or Tokens[k2].string != '(': + continue + # 命中:删除 `[new .. 类型名)`(须同行) + if Tok.start[0] != TypeTok.start[0]: + continue + StartCol: int = Tok.start[1] + EndCol: int = TypeTok.start[1] + Line0: str = Lines0[Tok.start[0] - 1] + Edits.append((Tok.start[0], StartCol, EndCol, '', Line0[StartCol:EndCol])) + return _ApplySameLineEdits(Code, Edits) + + def _ExpandSoftKeywordsImpl(Code: str) -> str: """ExpandSoftKeywords 的实现体(无缓存,供缓存未命中时调用)。""" Code = _SOFT_KEYWORD_RE.sub(lambda m: f'{m.group(1)}def{m.group(3)}', Code) + # `new` 生命周期软关键字(TPV):尽早展开成裸构造,后续各层不再看到 descriptors。 + if 'new' in Code: + Code = _ExpandNewExprs(Code) if 'enum' in Code: Code = _ExpandEnumBlocks(Code) if 'union' in Code: