feat(vast_c): extern/export 完整语义(注解改写+标记)并接入 vast.parse

- ParseExternDef:支持 4 种语法(extern/export [def] A(...) -> T [': pass']),返回注解改写为 <原类型> | t.State(extern)/ <原类型> | t.CExport(export),节点设 Extern=True/Export=True(对齐 vast Parser._ParseExternDef/_ParseExportDef)
- MakeTAttrNode:构造 t.Attr 注解节点(Attribute(Name('t'), attr))
- vast.parse 接入:默认走 vast_c C 加速路径(VAST_USE_C=0 禁用,=strict fail-fast 直接抛),异常回退纯 Python vast
- 差分测试 83/83 全绿(新增 7 个 extern/export 用例);includes/ 与 TransPyV/App 4 个真实 .vp 文件 C 路径与纯 Python 输出一致
This commit is contained in:
TermiNexus committed 2026-08-18 06:59:10 +08:00
1 parent d13b966604
commit 6350b81307
2 files changed
+186 -13

No files matched your search

+158 -2
View File
@@ -3930,6 +3930,7 @@ static PyObject *ParseMatch(Parser *P);
static PyObject *ParseFunctionDef(Parser *P, int IsAsync, PyObject *Decorators);
static PyObject *ParseClassDef(Parser *P, PyObject *Decorators);
static PyObject *ParseExprList(Parser *P);
static PyObject *ParseExternDef(Parser *P, int IsExport, PyObject *Decorators);
static PyObject *TryParseAnnAssign(Parser *P);
static PyObject *ParseExprStmt(Parser *P);
static PyObject *ParseImport(Parser *P);
@@ -3990,10 +3991,10 @@ static PyObject *ParseStatement(Parser *P) {
Token *T = PeekTok(P, 0);
if (T->Kind == TK_NAME) {
if (TokIsName(T, "extern")) {
return ParseFunctionDef(P, 0, NULL); /* extern 简化为普通 def(测试未覆盖,宽松) */
return ParseExternDef(P, 0, NULL);
}
if (TokIsName(T, "export")) {
return ParseFunctionDef(P, 0, NULL);
return ParseExternDef(P, 1, NULL);
}
if ((TokIsName(T, "fn") || TokIsName(T, "fun") || TokIsName(T, "func")
|| TokIsName(T, "function"))
@@ -4834,6 +4835,161 @@ static PyObject *ParseFunctionDef(Parser *P, int IsAsync, PyObject *Decorators)
return Node;
}
/* 构造 t.Attr 注解节点:Attribute(value=Name('t', Load), attr=AttrName, ctx=Load) */
static PyObject *MakeTAttrNode(Parser *P, const char *AttrName) {
PyObject *Load = MakeCtx(P, "Load");
PyObject *TName = PyUnicode_FromString("t");
if (Load == NULL || TName == NULL) {
Py_XDECREF(Load);
Py_XDECREF(TName);
return NULL;
}
PyObject *ArgvN[2] = { TName, Load };
PyObject *TNode = NewNode(P, "Name", ArgvN, 2);
Py_DECREF(TName);
Py_DECREF(Load);
if (TNode == NULL) {
return NULL;
}
PyObject *Load2 = MakeCtx(P, "Load");
PyObject *AttrStr = PyUnicode_FromString(AttrName);
if (Load2 == NULL || AttrStr == NULL) {
Py_XDECREF(TNode);
Py_XDECREF(Load2);
Py_XDECREF(AttrStr);
return NULL;
}
PyObject *ArgvA[3] = { TNode, AttrStr, Load2 };
PyObject *AttrNode = NewNode(P, "Attribute", ArgvA, 3);
Py_DECREF(TNode);
Py_DECREF(AttrStr);
Py_DECREF(Load2);
return AttrNode;
}
/* extern/export 函数声明(FFI/裸名导出,对齐 vast Parser._ParseExternDef/_ParseExportDef)。
* 允许语法(4 种,配不配 def 都一样,无 `:` 时 body 为空):
* extern [def] A(x: int) -> int [': pass']
* 产出标准 FunctionDef:返回注解改写为 <原类型> | t.State(extern)/ <原类型> | t.CExport(export),
* 并设 Extern=True / Export=True 供 Unparser 还原。 */
static PyObject *ParseExternDef(Parser *P, int IsExport, PyObject *Decorators) {
Token *Start = NextTok(P); /* 'extern' / 'export' */
if (AtName(P, "def")) {
NextTok(P);
}
Token *NameTok = ExpectName(P, NULL);
if (NameTok == NULL) {
return NULL;
}
PyObject *TypeParams = NewList();
if (TypeParams == NULL) {
return NULL;
}
if (AtOp(P, "[")) {
Py_DECREF(TypeParams);
TypeParams = ParseTypeParams(P);
if (TypeParams == NULL) {
return NULL;
}
}
PyObject *Args = ParseArguments(P, 0, 0);
if (Args == NULL) {
Py_DECREF(TypeParams);
return NULL;
}
PyObject *Returns = NULL;
if (AtOp(P, "->")) {
NextTok(P);
Returns = ParseExpr(P);
if (Returns == NULL) {
Py_DECREF(Args);
Py_DECREF(TypeParams);
return NULL;
}
}
PyObject *Body = NewList();
if (Body == NULL) {
Py_DECREF(Args);
Py_XDECREF(Returns);
Py_DECREF(TypeParams);
return NULL;
}
if (AtOp(P, ":")) {
NextTok(P);
Py_DECREF(Body);
Body = ParseSuite(P);
if (Body == NULL) {
Py_DECREF(Args);
Py_XDECREF(Returns);
Py_DECREF(TypeParams);
return NULL;
}
}
PyObject *Name = PyUnicode_FromStringAndSize(NameTok->Start, NameTok->End - NameTok->Start);
if (Name == NULL) {
Py_DECREF(Args);
Py_XDECREF(Returns);
Py_DECREF(TypeParams);
Py_DECREF(Body);
return NULL;
}
PyObject *Argv[7];
Argv[0] = Name;
Argv[1] = Args;
Argv[2] = Body;
Argv[3] = Decorators ? Decorators : NewList();
Argv[4] = Returns ? Returns : Py_None;
Argv[5] = Py_None; /* type_comment */
Argv[6] = TypeParams;
if (Argv[3] == NULL) {
Py_DECREF(Name);
Py_DECREF(Args);
Py_DECREF(Body);
Py_XDECREF(Returns);
Py_DECREF(TypeParams);
return NULL;
}
PyObject *Node = NewNode(P, "FunctionDef", Argv, 7);
Py_DECREF(Name);
Py_DECREF(Args);
Py_DECREF(Body);
if (Argv[3] != Decorators) {
Py_DECREF(Argv[3]);
}
Py_DECREF(TypeParams);
if (Node == NULL) {
Py_XDECREF(Returns);
return NULL;
}
/* 标记 extern/export(Unparser 据此还原语法) */
PyObject_SetAttrString(Node, IsExport ? "Export" : "Extern", Py_True);
/* 返回注解改写:<原类型> | t.State / <原类型> | t.CExport(NewNode 后 Returns 引用仍有效) */
PyObject *TAttr = MakeTAttrNode(P, IsExport ? "CExport" : "State");
if (TAttr != NULL) {
if (Returns != NULL) {
PyObject *Op = MakeSingleton(P, "BitOr");
if (Op != NULL) {
PyObject *ArgvB[3];
ArgvB[0] = Returns;
ArgvB[1] = Op;
ArgvB[2] = TAttr;
PyObject *Bin = NewNode(P, "BinOp", ArgvB, 3);
if (Bin != NULL) {
PyObject_SetAttrString(Node, "returns", Bin);
Py_DECREF(Bin);
}
Py_DECREF(Op);
}
} else {
PyObject_SetAttrString(Node, "returns", TAttr);
}
Py_DECREF(TAttr);
}
Py_XDECREF(Returns);
FixLoc(P, Node, Start);
return Node;
}
/* PEP 695 类型参数:[T, *Ts, **P, U: Bound] */
static PyObject *ParseTypeParams(Parser *P) {
if (!ExpectOp(P, "[")) {