fix(ast): parser.vp 去掉不存在的 ast. 命名空间前缀
parser.vp 位于 ast 包内、并没有 import ast,写 ast.Call* / ast.ASTKind.X 会把变量注解记成模块限定名 ast.Call,走到 lookup_field_by_class 的模块限定分支就 fail-fast:类 ast.Call 未找到(模块 ast 可解析 sha1=1abcd5277fa442de,但 Call 实际注册在定义模块 5df907d3a02a0bac 下)。全部改用本文件已导入的裸名(AST / ASTKind / Call / Name / Attribute),共 36 处。
This commit is contained in:
1 parent
6b88b3feff
commit
5e1180fc26
1 file changed
+72
-72
+72
-72
@@ -54,12 +54,12 @@ class Parser:
|
||||
prev: rawptr[Token] # 上一个被消费的 token(供 `T*(x)` 紧邻判据)
|
||||
pool: rawptr[memhub.MemManager] # memory pool
|
||||
error_count: int # error count
|
||||
pending_decorators: rawptr[list[rawptr[AST]]] # pending decorators list
|
||||
# `static` 修饰符(软关键字)挂起标记:语句起始消费 `static`(后随变量声明
|
||||
# `Name :`)后置 1,由紧随的 `_parse_type_ann` 在类型联合最左插入 t.CStatic
|
||||
# 标记(`static x: int = 0` → `x: t.CStatic | int = 0`),插入后立即清零,
|
||||
# 只作用于紧随其后的这一个注解。函数分支不经此通道(改走合成 @t.CStatic
|
||||
# 装饰器,与 inline def 同构,见 _ParseStaticModified)。
|
||||
pending_decorators: rawptr[list[rawptr[AST]]] # pending decorators list
|
||||
# `static` 修饰符(软关键字)挂起标记:语句起始消费 `static`(后随变量声明
|
||||
# `Name :`)后置 1,由紧随的 `_parse_type_ann` 在类型联合最左插入 t.CStatic
|
||||
# 标记(`static x: int = 0` → `x: t.CStatic | int = 0`),插入后立即清零,
|
||||
# 只作用于紧随其后的这一个注解。函数分支不经此通道(改走合成 @t.CStatic
|
||||
# 装饰器,与 inline def 同构,见 _ParseStaticModified)。
|
||||
pending_static: int
|
||||
# 当前正在解析的套件的**直接拥有者**是否 class(1=类体,0=其它)。
|
||||
# 由 _parse_suite_into_children 按 owner_is_class 维护,供 virtual/novirtual
|
||||
@@ -382,24 +382,24 @@ def _IsDescriptorKeyword(ps: rawptr[Parser]) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def _IsMagicAttributeCall(ps: rawptr[Parser]) -> int:
|
||||
"""注解位置的 `__attribute__(...)` 前缀判定,1=是 / 0=否
|
||||
|
||||
`__attribute__` 是软关键字(不进关键字表):只在**注解位置**、且紧跟 '(' 时
|
||||
由本处消费;作普通标识符/装饰器名(`@__attribute__(...)` 走装饰器通道)都不受影响。
|
||||
语义与 const / volatile 描述符同族:顺序自由、可混写。
|
||||
"""
|
||||
if _cur_type(ps) != TokenType.Name:
|
||||
return 0
|
||||
s: str = _cur_str(ps)
|
||||
if s is None or string.strcmp(s, "__attribute__") != 0:
|
||||
return 0
|
||||
nxt: rawptr[Token] = ps.cur.next
|
||||
if nxt is None or nxt.type != TokenType.Op or nxt.op_subtype != TokOp.LPar:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
def _IsMagicAttributeCall(ps: rawptr[Parser]) -> int:
|
||||
"""注解位置的 `__attribute__(...)` 前缀判定,1=是 / 0=否
|
||||
|
||||
`__attribute__` 是软关键字(不进关键字表):只在**注解位置**、且紧跟 '(' 时
|
||||
由本处消费;作普通标识符/装饰器名(`@__attribute__(...)` 走装饰器通道)都不受影响。
|
||||
语义与 const / volatile 描述符同族:顺序自由、可混写。
|
||||
"""
|
||||
if _cur_type(ps) != TokenType.Name:
|
||||
return 0
|
||||
s: str = _cur_str(ps)
|
||||
if s is None or string.strcmp(s, "__attribute__") != 0:
|
||||
return 0
|
||||
nxt: rawptr[Token] = ps.cur.next
|
||||
if nxt is None or nxt.type != TokenType.Op or nxt.op_subtype != TokOp.LPar:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
def _MakeDescriptorMarker(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
"""由当前描述符关键字构造标记节点 Attribute(Name('t'), 'CConst'/'CVolatile')。
|
||||
|
||||
@@ -754,24 +754,24 @@ def _IsStaticModifier(ps: rawptr[Parser]) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def _IsStaticDescriptorKeyword(ps: rawptr[Parser]) -> int:
|
||||
"""当前 token 是否为注解位置的 `static` 描述符(软关键字),1=是 / 0=否
|
||||
|
||||
与 const / volatile 同族:只在注解位置(`:` 后的 AnnAssign/形参注解、`->` 后的
|
||||
返回注解)由 `_parse_type_ann` 消费,作标识符的位置不受影响。
|
||||
支持 `名字: static 类型` 写法(ViperOS 驱动广泛使用:`pack_head: static uint32 = 0`),
|
||||
与语句起始的 `static 名字: 类型`(pending_static 通道)、手写 `t.CStatic | T`
|
||||
**三处同源**——都落成同一个 `t.CStatic` 标记(此前注解位置的 static 未被消费,
|
||||
退化成一个叫 static 的"类名",被建成 opaque 结构体 @a = global %"sha1.static")。
|
||||
"""
|
||||
if _cur_type(ps) != TokenType.Name:
|
||||
return 0
|
||||
s: str = _cur_str(ps)
|
||||
if s is None or string.strcmp(s, "static") != 0:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
def _IsStaticDescriptorKeyword(ps: rawptr[Parser]) -> int:
|
||||
"""当前 token 是否为注解位置的 `static` 描述符(软关键字),1=是 / 0=否
|
||||
|
||||
与 const / volatile 同族:只在注解位置(`:` 后的 AnnAssign/形参注解、`->` 后的
|
||||
返回注解)由 `_parse_type_ann` 消费,作标识符的位置不受影响。
|
||||
支持 `名字: static 类型` 写法(ViperOS 驱动广泛使用:`pack_head: static uint32 = 0`),
|
||||
与语句起始的 `static 名字: 类型`(pending_static 通道)、手写 `t.CStatic | T`
|
||||
**三处同源**——都落成同一个 `t.CStatic` 标记(此前注解位置的 static 未被消费,
|
||||
退化成一个叫 static 的"类名",被建成 opaque 结构体 @a = global %"sha1.static")。
|
||||
"""
|
||||
if _cur_type(ps) != TokenType.Name:
|
||||
return 0
|
||||
s: str = _cur_str(ps)
|
||||
if s is None or string.strcmp(s, "static") != 0:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
def _MakeStaticMarker(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
"""构造标记节点 Attribute(Name('t'), 'CStatic')
|
||||
|
||||
@@ -1151,8 +1151,8 @@ def _parse_test(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
if _IsVolatileCallPrefix(ps) != 0:
|
||||
_advance(ps) # 消费 volatile
|
||||
vinner: rawptr[AST] = _parse_test(ps)
|
||||
if vinner is not None and vinner.kind() == ast.ASTKind.Call:
|
||||
(ast.Call*(vinner)).IsVolatile = 1
|
||||
if vinner is not None and vinner.kind() == ASTKind.Call:
|
||||
(Call*(vinner)).IsVolatile = 1
|
||||
return vinner
|
||||
left: rawptr[AST] = _parse_or_test(ps)
|
||||
if left is None: return None
|
||||
@@ -1464,7 +1464,7 @@ def _at_ptr_suffix(ps: rawptr[Parser], base: rawptr[AST]) -> int:
|
||||
|
||||
判据(与 vast 一致):base 是类型原子(Name/Attribute/Subscript),
|
||||
且从当前 '*'/'**' 起跨过连续 '*'/'**' 与 Nl 后,紧跟 ']' / ',' / ')' / ':' / '='。
|
||||
该判据同时覆盖注解与表达式上下文(如 list[ast.AST*] / list[ast.AST*]*)。
|
||||
该判据同时覆盖注解与表达式上下文(如 list[AST*] / list[AST*]*)。
|
||||
"""
|
||||
if base is None:
|
||||
return 0
|
||||
@@ -2583,9 +2583,9 @@ def _parse_type_ann(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
ac_node: rawptr[AST] = _parse_test(ps)
|
||||
if ac_node is None:
|
||||
break
|
||||
if ac_node.kind() != ast.ASTKind.Call:
|
||||
if ac_node.kind() != ASTKind.Call:
|
||||
break
|
||||
ac: ast.Call* = ast.Call*(ac_node)
|
||||
ac: Call* = Call*(ac_node)
|
||||
if ac.args is not None:
|
||||
acn: sizet = len(ac.args)
|
||||
aci: sizet = 0
|
||||
@@ -4235,24 +4235,24 @@ def _parse_match_case(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
# 原样识别(零新增判据);也即同时适用于 class 与 def(装饰器链共用本函数)。
|
||||
# 容错:实参已是 `t.attr.X` / `c.Attribute(...)` 形态时原样保留(允许混写)。
|
||||
# ============================================================
|
||||
def _IsMagicAttributeCallee(node: ast.AST*) -> int:
|
||||
def _IsMagicAttributeCallee(node: AST*) -> int:
|
||||
"""节点是否为 `__attribute__`(Name 形态,或 X.__attribute__ 的尾段形态)"""
|
||||
if node is None:
|
||||
return 0
|
||||
k: int = node.kind()
|
||||
if k == ast.ASTKind.Name:
|
||||
nm: ast.Name* = ast.Name*(node)
|
||||
if k == ASTKind.Name:
|
||||
nm: Name* = Name*(node)
|
||||
if nm.id is not None and string.strcmp(nm.id, "__attribute__") == 0:
|
||||
return 1
|
||||
return 0
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute* = ast.Attribute*(node)
|
||||
if k == ASTKind.Attribute:
|
||||
at: Attribute* = Attribute*(node)
|
||||
if at.attr is not None and string.strcmp(at.attr, "__attribute__") == 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def _MakeTAttrMarker(ps: rawptr[Parser], arg: ast.AST*) -> ast.AST*:
|
||||
def _MakeTAttrMarker(ps: rawptr[Parser], arg: AST*) -> AST*:
|
||||
"""把一个 __attribute__ 实参 desugar 为 `t.attr.<name>`(带调用则保留实参)
|
||||
|
||||
- `always_inline`(Name) → `t.attr.always_inline`
|
||||
@@ -4262,43 +4262,43 @@ def _MakeTAttrMarker(ps: rawptr[Parser], arg: ast.AST*) -> ast.AST*:
|
||||
if arg is None:
|
||||
return None
|
||||
k: int = arg.kind()
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at0: ast.Attribute* = ast.Attribute*(arg)
|
||||
if at0.value is not None and at0.value.kind() == ast.ASTKind.Attribute:
|
||||
if k == ASTKind.Attribute:
|
||||
at0: Attribute* = Attribute*(arg)
|
||||
if at0.value is not None and at0.value.kind() == ASTKind.Attribute:
|
||||
return arg
|
||||
return arg
|
||||
attr_root: ast.AST* = Attribute(ps.pool, Name(ps.pool, "t", ASTCtx.Load),
|
||||
attr_root: AST* = Attribute(ps.pool, Name(ps.pool, "t", ASTCtx.Load),
|
||||
"attr", ASTCtx.Load)
|
||||
if k == ast.ASTKind.Name:
|
||||
nm2: ast.Name* = ast.Name*(arg)
|
||||
if k == ASTKind.Name:
|
||||
nm2: Name* = Name*(arg)
|
||||
if nm2.id is None:
|
||||
return arg
|
||||
mk: ast.AST* = Attribute(ps.pool, attr_root, nm2.id, ASTCtx.Load)
|
||||
mk: AST* = Attribute(ps.pool, attr_root, nm2.id, ASTCtx.Load)
|
||||
_set_pos(mk, nm2.lineno, nm2.col_offset, 0, 0)
|
||||
return mk
|
||||
if k == ast.ASTKind.Call:
|
||||
cl2: ast.Call* = ast.Call*(arg)
|
||||
if cl2.func is None or cl2.func.kind() != ast.ASTKind.Name:
|
||||
if k == ASTKind.Call:
|
||||
cl2: Call* = Call*(arg)
|
||||
if cl2.func is None or cl2.func.kind() != ASTKind.Name:
|
||||
return arg
|
||||
fnm: ast.Name* = ast.Name*(cl2.func)
|
||||
fnm: Name* = Name*(cl2.func)
|
||||
if fnm.id is None:
|
||||
return arg
|
||||
inner: ast.AST* = Attribute(ps.pool, attr_root, fnm.id, ASTCtx.Load)
|
||||
inner: AST* = Attribute(ps.pool, attr_root, fnm.id, ASTCtx.Load)
|
||||
_set_pos(inner, fnm.lineno, fnm.col_offset, 0, 0)
|
||||
mk2: ast.AST* = Call(ps.pool, inner, cl2.args, cl2.keywords)
|
||||
mk2: AST* = Call(ps.pool, inner, cl2.args, cl2.keywords)
|
||||
_set_pos(mk2, cl2.lineno, cl2.col_offset, 0, 0)
|
||||
return mk2
|
||||
return arg
|
||||
|
||||
|
||||
def _DesugarMagicAttribute(ps: rawptr[Parser], expr: ast.AST*) -> ast.AST*:
|
||||
def _DesugarMagicAttribute(ps: rawptr[Parser], expr: AST*) -> AST*:
|
||||
"""`@__attribute__(...)` → `@c.Attribute(t.attr.x, ...)`;其它装饰器原样返回"""
|
||||
if expr is None or expr.kind() != ast.ASTKind.Call:
|
||||
if expr is None or expr.kind() != ASTKind.Call:
|
||||
return expr
|
||||
cl: ast.Call* = ast.Call*(expr)
|
||||
cl: Call* = Call*(expr)
|
||||
if _IsMagicAttributeCallee(cl.func) == 0:
|
||||
return expr
|
||||
c_func: ast.AST* = Attribute(ps.pool, Name(ps.pool, "c", ASTCtx.Load),
|
||||
c_func: AST* = Attribute(ps.pool, Name(ps.pool, "c", ASTCtx.Load),
|
||||
"Attribute", ASTCtx.Load)
|
||||
new_args: rawptr[list[rawptr[AST]]] = list[rawptr[AST]](ps.pool, 8)
|
||||
if new_args is None:
|
||||
@@ -4307,11 +4307,11 @@ def _DesugarMagicAttribute(ps: rawptr[Parser], expr: ast.AST*) -> ast.AST*:
|
||||
an: sizet = len(cl.args)
|
||||
ai: sizet = 0
|
||||
while ai < an:
|
||||
mk: ast.AST* = _MakeTAttrMarker(ps, cl.args.get(ai))
|
||||
mk: AST* = _MakeTAttrMarker(ps, cl.args.get(ai))
|
||||
if mk is not None:
|
||||
new_args.append(mk)
|
||||
ai += 1
|
||||
new_call: ast.AST* = Call(ps.pool, c_func, new_args, None)
|
||||
new_call: AST* = Call(ps.pool, c_func, new_args, None)
|
||||
_set_pos(new_call, cl.lineno, cl.col_offset, 0, 0)
|
||||
return new_call
|
||||
|
||||
|
||||
Reference in new issue
Block a user