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:
1 parent
d13b966604
commit
6350b81307
2 files changed
+186
-13
No files matched your search
+158
-2
@@ -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, "[")) {
|
||||
|
||||
Reference in new issue
Block a user