From 5e1180fc26f2fa1cb63457ae7af397bdb405ae90 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sun, 27 Sep 2026 16:53:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(ast):=20parser.vp=20=E5=8E=BB=E6=8E=89?= =?UTF-8?q?=E4=B8=8D=E5=AD=98=E5=9C=A8=E7=9A=84=20ast.=20=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E7=A9=BA=E9=97=B4=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 处。 --- ast/parser.vp | 144 +++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/ast/parser.vp b/ast/parser.vp index 91f1bf7..ee556a2 100644 --- a/ast/parser.vp +++ b/ast/parser.vp @@ -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.`(带调用则保留实参) - `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