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:
1 parent
aa9042173e
commit
ce568e10b7
6 files changed
+114
-12
No files matched your search
@@ -54,6 +54,9 @@ class Parser(ExprParserMixin):
|
||||
tok: Token = self._Peek()
|
||||
if tok.Type == NAME:
|
||||
v: str = tok.Value
|
||||
# extern 函数声明(FFI,等价 t.State)——必须在软关键字 def 分派之前
|
||||
if v == 'extern':
|
||||
return self._ParseExternDef()
|
||||
# 软关键字函数定义:fn/fun/func/function + 标识符
|
||||
if v in SOFT_KEYWORDS and self._Peek(1).Type == NAME:
|
||||
return self._ParseFunctionDef()
|
||||
@@ -493,6 +496,8 @@ class Parser(ExprParserMixin):
|
||||
self._ExpectNEWLINE()
|
||||
self._SkipNEWLINE()
|
||||
tok: Token = self._Peek()
|
||||
if tok.Type == NAME and tok.Value == 'extern':
|
||||
return self._ParseExternDef(decorators=decorator_list)
|
||||
if tok.Type == NAME and tok.Value == 'def':
|
||||
return self._ParseFunctionDef(decorators=decorator_list)
|
||||
if tok.Type == NAME and tok.Value == 'async':
|
||||
@@ -532,6 +537,51 @@ class Parser(ExprParserMixin):
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
|
||||
def _ParseExternDef(self, decorators: list[N.expr] | None = None) -> N.FunctionDef:
|
||||
"""解析 extern 函数声明(FFI,与 t.State 作用相当)。
|
||||
|
||||
允许语法(均声明不定义,不生成函数体):
|
||||
extern def A(x: int) -> int: pass
|
||||
extern A(x: int) -> int: pass
|
||||
extern def A(x: int) -> int
|
||||
extern A(x: int) -> int
|
||||
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | t.State``
|
||||
以复用 TPC 的 IsState 路径;并设自定义属性 ``Extern = True``
|
||||
供 Unparser 还原 extern 语法。
|
||||
"""
|
||||
start: Token = self._Next() # 'extern'
|
||||
if self._AtName('def'):
|
||||
self._Next()
|
||||
name_tok: Token = self._ExpectName()
|
||||
type_params: list[N.AST] = []
|
||||
if self._AtOp('['):
|
||||
type_params = self._ParseTypeParams()
|
||||
args: N.arguments = self._ParseArguments()
|
||||
returns: N.expr | None = None
|
||||
if self._AtOp('->'):
|
||||
self._Next()
|
||||
returns = self.ParseExpr()
|
||||
body: list[N.stmt] = []
|
||||
if self._AtOp(':'):
|
||||
self._Next()
|
||||
body = self._ParseSuite()
|
||||
node: N.FunctionDef = N.FunctionDef(
|
||||
name=name_tok.Value, args=args, body=body,
|
||||
decorator_list=decorators or [], returns=returns,
|
||||
type_comment=None, type_params=type_params,
|
||||
)
|
||||
node.Extern = True
|
||||
# 返回注解改写为 <原类型> | t.State,使 TPC 识别为 State 函数(仅声明)
|
||||
state_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='State', ctx=N.Load())
|
||||
if returns is not None:
|
||||
node.returns = N.BinOp(left=returns, op=N.BitOr(), right=state_attr)
|
||||
else:
|
||||
node.returns = state_attr
|
||||
self._FixLoc(node, start)
|
||||
return node
|
||||
|
||||
def _ParseTypeParams(self) -> list[N.AST]:
|
||||
"""解析 PEP 695 类型参数:[T, *Ts, **P, U: Bound]"""
|
||||
self._ExpectOp('[')
|
||||
|
||||
Reference in new issue
Block a user