feat(vast/ast): 新增 extern 软关键字声明 FFI 函数(等价 t.State)

TPC 侧 vast:
- extern [def] A(...) [-> T] [: pass] 四种语法解析为 FunctionDef
- 返回注解改写为 <原类型> | t.State,复用 TPC 的 IsState 外部函数路径
- 设 Extern 标记,Unparser 还原 extern 语法(round-trip 一致)

TPV 侧 includes/ast(自举前端):
- Keyword.Extern 枚举与 intern,_is_funcdef_kw 软判定
  (extern def / extern Name+'( 或 '[')
- _parse_funcdef 支持无冒号声明、FLAG_IS_EXTERN 标记、
  returns 改写为 <原类型> | t.State(vpi 含 State → 定义端裸名 + 不生成函数体)
This commit is contained in:
TermiNexus committed 2026-08-17 10:41:44 +08:00
1 parent aa9042173e
commit ce568e10b7
6 files changed
+114 -12

No files matched your search

+11 -3
View File
@@ -72,12 +72,20 @@ class Unparser:
return '\n'.join(lines)
def _FunctionDef(self, node: N.FunctionDef) -> str:
kw: str = 'async def' if isinstance(node, N.AsyncFunctionDef) else 'def'
is_extern: bool = bool(getattr(node, 'Extern', False))
kw: str = 'async def' if isinstance(node, N.AsyncFunctionDef) else ('extern def' if is_extern else 'def')
decos: str = ''.join(f'@{self._expr(d)}\n' for d in node.decorator_list)
params: str = self._Arguments(node.args)
ret: str = ''
if node.returns is not None:
ret = f' -> {self._expr(node.returns)}'
returns: N.expr | None = node.returns
if is_extern and isinstance(returns, N.BinOp) and isinstance(returns.op, N.BitOr):
# 还原 extern 原始注解:去掉改写时追加的 | t.State
right: N.expr = returns.right
if (isinstance(right, N.Attribute) and right.attr == 'State'
and isinstance(right.value, N.Name) and right.value.id == 't'):
returns = returns.left
if returns is not None:
ret = f' -> {self._expr(returns)}'
body: str = self._Block(node.body)
return f'{decos}{kw} {node.name}({params}){ret}:\n{body}'