feat(preprocess): ExpandSoftKeywords 增加 new 生命周期软关键字展开
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 仍作标识符,跨行不处理。
This commit is contained in:
1 parent
04acaa3dd5
commit
18d753999d
1 file changed
+83
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user