fix(descriptor): static 作为注解位置存储类描述符(名字: static T)

_TYPE_DESCRIPTOR_MARKERS 增加 static -> CStatic,与 const/volatile 共用同一展开器与注解位置判据;static 仅在注解位置生效(冒号后 / 形参 / 返回箭头后),非注解位置的 static 标识符与 static_libs 之类子串不受影响。缺类型(a: static)现在响亮失败而非静默退化。

修用户报告:a: static int(TransPyV/App/main.vp:56,ViperOS 驱动同款 pack_head: static uint32 = 0 广泛使用)此前注解位置未被消费,static 退化成一个类名并被建成 opaque 结构体,产出 a 的类型为 模块sha1 点 static 的 zeroinitializer 全局,llvm-link 报 invalid type for null constant。现展开为 a: t.CStatic | int。

回归:306 个 .vp 中 105 行被改且全部含 const/volatile/static,0 处意外改动;main.vp / mouse.vp / keyboard.vp / devfs.vp / fat32_types.vp 展开后 vast.parse 全部通过。
This commit is contained in:
TermiNexus committed 2026-09-27 14:18:45 +08:00
1 parent 64538e08f8
commit ae02431dd2
1 file changed
+17 -8
+17 -8
View File
@@ -315,8 +315,12 @@ def _ExpandTypedefs(Code: str) -> str:
# (BinOp(BitOr, Attribute(t,'CConst'), <类型>)),产出与手写形态逐字段同形。
#
# 软关键字边界(唯一识别面 = "注解位置 + token 相邻",与 array 那次同口径):
# const/volatile 只在该位置生效——修饰符串的前一个 token 是 `:` 且再前一个是
# const/volatile/static 只在该位置生效——修饰符串的前一个 token 是 `:` 且再前一个是
# Name(注解目标:`a:` / `self.x:` / 形参名),或前一个 token 是 `->`(返回注解)。
# `static` 与另两者同源:ViperOS 驱动广泛写 `pack_head: static uint32 = 0`,
# 注解位置未被消费时会退化成一个叫 static 的"类名"(被建成 opaque 结构体
# `@a = global %"<sha1>.static" zeroinitializer`,llvm-link 报 invalid type for
# null constant)——故必须与 const/volatile 同路径脱糖为 `t.CStatic | T`。
# 非类型位置**原样保留**为普通标识符(不做词法保留字):
# - `t.attr.const()`(TransPyV/Test/App/attr_test.vp:142,全仓 .vp 代码内唯一出现)
# - `const = 5` / `x = const` / `d = {"k": const}`
@@ -327,13 +331,16 @@ def _ExpandTypedefs(Code: str) -> str:
# `a: const`(缺类型)/ `a: const = 1` / `a: const 1`(后随非类型)/ 裸 `const` 语句。
# 报文含 行:列 + 源码片段 + 期望形态 + 正确示例(文件名由调用方的 SyntaxError
# 上报路径补全,与 _ExpandTypedefs / TPV dump_parse_traceback 同约定)。
_TYPE_DESCRIPTOR_MARKERS: dict[str, str] = {'const': 'CConst', 'volatile': 'CVolatile'}
_TYPE_DESCRIPTOR_MARKERS: dict[str, str] = {
'const': 'CConst', 'volatile': 'CVolatile', 'static': 'CStatic',
}
_DESCRIPTOR_SKIP_TYPES: tuple[int, ...] = (tokenize.COMMENT, tokenize.NL)
_DESCRIPTOR_HINT: str = (
'`名字: const 类型` / `名字: volatile 类型`(可组合:`名字: const volatile 类型`)'
'`名字: const 类型` / `名字: volatile 类型` / `名字: static 类型`'
'(可组合:`名字: const volatile 类型`)'
)
_DESCRIPTOR_EXAMPLE: str = (
'a: const int / a: volatile int / a: const volatile t.CInt32T / '
'a: const int / a: volatile int / a: static uint32 / a: const volatile t.CInt32T / '
'def f(p: const rawptr[Foo]) -> const int'
)
@@ -350,7 +357,7 @@ def _TypeDescriptorSyntaxError(Detail: str, Lineno: int, Col: int, Snippet: str)
"""构造类型描述符非法形态的 fail-fast 报文(行:列 + 源码片段 + 期望形态 + 正确示例)。"""
return SyntaxError(
f"[TPC] 类型描述符非法({Detail}):行 {Lineno} 列 {Col},源码片段 {Snippet.strip()!r}。"
f"const/volatile 是只在**类型位置**生效的软关键字,必须写成 {_DESCRIPTOR_HINT};"
f"const/volatile/static 是只在**类型位置**生效的软关键字,必须写成 {_DESCRIPTOR_HINT};"
f"正确示例:{_DESCRIPTOR_EXAMPLE}。"
f"(描述符不会被静默忽略:缺类型 / 后随非类型 / 裸用一律终止编译)"
)
@@ -842,7 +849,7 @@ def _ExpandAttributeDescriptors(Code: str) -> str:
def _ExpandTypeDescriptors(Code: str) -> str:
"""把 `const T` / `volatile T`(含组合、任意顺序)展开为 `t.CConst | T` 形态(行号不变)。
"""把 `const T` / `volatile T` / `static T`(含组合、任意顺序)展开为 `t.CConst | T` 等形态(行号不变)。
- 词法级切分(`tokenize`):注释/字符串内容天然不参与,不会被误改写。
- 只在"注解位置"(前一个 token 是 `:` 且再前一个是 Name,或前一个 token 是 `->`)
@@ -853,7 +860,7 @@ def _ExpandTypeDescriptors(Code: str) -> str:
- `const [N]T` (C-style leading array prefix) desugars to
`t.CConst | t.CArray[T, N]`; see _DesugarArrayPrefix.
"""
if 'const' not in Code and 'volatile' not in Code:
if 'const' not in Code and 'volatile' not in Code and 'static' not in Code:
return Code
try:
Tokens: list = list(tokenize.generate_tokens(io.StringIO(Code).readline))
@@ -1308,7 +1315,9 @@ def _ExpandSoftKeywordsImpl(Code: str) -> str:
# 且它自身产出的 `t.attr.X |` 不会干扰紧随的 const/volatile 展开。
if _ATTRIBUTE_CALLEE in Code:
Code = _ExpandAttributeDescriptors(Code)
if 'const' in Code or 'volatile' in Code:
# static 与 const/volatile 同为注解位置的存储类描述符(`名字: static uint32 = 0`,
# ViperOS 驱动广泛使用);三者共用同一展开器与同一 marker 表。
if 'const' in Code or 'volatile' in Code or 'static' in Code:
Code = _ExpandTypeDescriptors(Code)
# 裸 `[N]T` 数组前缀在描述符之后:`const [N]T` 已由 _ExpandTypeDescriptors 消化为
# `t.CConst | t.CArray[T, N]`(此处不再有注解位置的裸 '['),避免两条路径重复改写。