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
@@ -154,6 +154,7 @@ CONST_CHAR: t.CDefine = 6
|
||||
FLAG_IS_ASYNC: t.CDefine = 1
|
||||
FLAG_SIMPLE: t.CDefine = 2
|
||||
FLAG_HAS_STAR: t.CDefine = 4
|
||||
FLAG_IS_EXTERN: t.CDefine = 8
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
+47
-7
@@ -10,7 +10,7 @@ from .base import (
|
||||
_set_pos, _binop_from_op, _augop_from_op, _cmpop_from_op, _copy_str, _inherit_pos,
|
||||
_init_ast,
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE, CONST_CHAR,
|
||||
FLAG_IS_ASYNC,
|
||||
FLAG_IS_ASYNC, FLAG_IS_EXTERN,
|
||||
)
|
||||
from .exprs import (
|
||||
BoolOp, BinOp, UnaryOp, Lambda, IfExp, Dict, Set,
|
||||
@@ -94,15 +94,33 @@ def _cur_kw(ps: Parser | t.CPtr) -> t.CInt:
|
||||
|
||||
|
||||
def _is_funcdef_kw(ps: Parser | t.CPtr, kw: t.CInt) -> int:
|
||||
"""判断当前 token 是否为函数定义关键字(def 及其别名 fn/fun/func/function)
|
||||
"""判断当前 token 是否为函数定义关键字(def 及其别名 fn/fun/func/function,
|
||||
以及 extern 声明关键字)
|
||||
|
||||
def 是硬关键字直接判定;fn/fun/func/function 是软关键字,
|
||||
def 是硬关键字直接判定;fn/fun/func/function/extern 是软关键字,
|
||||
仅当下一个 token 是 Name 且再下一个是 '('(或泛型 '[T]' 前的 '[')时
|
||||
判定为函数定义。否则按普通标识符处理,兼容既有代码把 func 用作
|
||||
判定为函数定义。extern 还允许 'extern def A(...)' 形式(下一个是 def)。
|
||||
否则按普通标识符处理,兼容既有代码把 func 用作
|
||||
字段/参数名(如 AST 节点 func 字段、Call.func 注解 `func: AST | t.CPtr`)。
|
||||
"""
|
||||
if kw == Keyword.Def:
|
||||
return 1
|
||||
if kw == Keyword.Extern:
|
||||
# extern def A(...) 或 extern A(...)(extern 后是 def 或 Name+'(/'[')
|
||||
nxt: Token | t.CPtr = ps.cur.next
|
||||
if nxt is None:
|
||||
return 0
|
||||
if nxt.kw_subtype == Keyword.Def:
|
||||
return 1
|
||||
if nxt.type != TokenType.Name:
|
||||
return 0
|
||||
nxt2: Token | t.CPtr = nxt.next
|
||||
if nxt2 is None:
|
||||
return 0
|
||||
if nxt2.type == TokenType.Op \
|
||||
and (nxt2.op_subtype == TokOp.LPar or nxt2.op_subtype == TokOp.Lsqb):
|
||||
return 1
|
||||
return 0
|
||||
if kw == Keyword.Fn or kw == Keyword.Fun \
|
||||
or kw == Keyword.Func or kw == Keyword.Function:
|
||||
# 软关键字 lookahead: 下个是 Name,再下个是 '(' 或 '[T...]' 泛型参数(PEP 695)
|
||||
@@ -2210,7 +2228,15 @@ def _parse_with_item(ps: Parser | t.CPtr) -> AST | t.CPtr:
|
||||
def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr:
|
||||
lineno: t.CInt = _cur_lineno(ps)
|
||||
col: t.CInt = _cur_col(ps)
|
||||
_advance(ps) # def
|
||||
is_extern_fd: t.CInt = 0
|
||||
if _cur_kw(ps) == Keyword.Extern:
|
||||
# extern 声明:extern [def] A(...) [-> T] [": pass" 可选]
|
||||
is_extern_fd = 1
|
||||
_advance(ps) # extern
|
||||
if _cur_kw(ps) == Keyword.Def:
|
||||
_advance(ps)
|
||||
else:
|
||||
_advance(ps) # def / fn / ...
|
||||
if _cur_type(ps) != TokenType.Name:
|
||||
ps.error_count += 1
|
||||
return None
|
||||
@@ -2244,11 +2270,25 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr:
|
||||
returns: AST | t.CPtr = None
|
||||
if _accept_op(ps, TokOp.RArrow):
|
||||
returns = _parse_test(ps)
|
||||
_expect_op(ps, TokOp.Colon)
|
||||
if is_extern_fd:
|
||||
# extern 声明:返回注解改写为 <原类型> | t.State,复用既有
|
||||
# State/外部 C 函数识别路径(vpi 注解含 "State" → 定义端裸名 + 不生成函数体)
|
||||
state_attr_fd: AST | t.CPtr = Attribute(ps.pool,
|
||||
Name(ps.pool, "t", ASTCtx.Load),
|
||||
"State", ASTCtx.Load)
|
||||
if returns != None:
|
||||
returns = BinOp(ps.pool, returns, OpKind.BitOr, state_attr_fd)
|
||||
else:
|
||||
returns = state_attr_fd
|
||||
dec_list: list[AST | t.CPtr] | t.CPtr = ps.pending_decorators
|
||||
ps.pending_decorators = None
|
||||
node: FunctionDef | t.CPtr = FunctionDef(ps.pool, name, args, dec_list, returns, is_async, type_params_fd)
|
||||
_parse_suite_into_children(ps, node)
|
||||
if is_extern_fd:
|
||||
node.flags = node.flags | FLAG_IS_EXTERN
|
||||
if is_extern_fd == 0 or _match_op(ps, TokOp.Colon):
|
||||
_expect_op(ps, TokOp.Colon)
|
||||
_parse_suite_into_children(ps, node)
|
||||
# extern 无 ': pass' 形式(extern A(...) -> int):body 为空,仅声明
|
||||
_set_pos(node, lineno, col, 0, 0)
|
||||
return node
|
||||
|
||||
|
||||
@@ -77,6 +77,8 @@ class Keyword(t.CEnum):
|
||||
Fun: t.State
|
||||
Func: t.State
|
||||
Function: t.State
|
||||
# extern 函数声明关键字(FFI,等价 t.State 标记;软判定见 _is_funcdef_kw)
|
||||
Extern: t.State
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -255,7 +257,8 @@ def _init_keywords(pool: memhub.MemManager | t.CPtr):
|
||||
_kw_intern(pool, "fn", Keyword.Fn)
|
||||
_kw_intern(pool, "fun", Keyword.Fun)
|
||||
_kw_intern(pool, "func", Keyword.Func)
|
||||
_kw_intern(pool, "function", Keyword.Function)
|
||||
_kw_intern(pool, "function", Keyword.Function)
|
||||
_kw_intern(pool, "extern", Keyword.Extern)
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
Reference in new issue
Block a user