refactor(tpc): 退役 t/c 模块并将定宽类型升级为内建
删除 lib/includes/t.py、c.py,类型模型迁入 lib/core/TypeSystem.py;移除 IsTModule/_T_MODULE_NAMES 等名称判据,语法糖与内部标记统一为裸名;builtins 的 sizet/intN/uintN/fast/least/uchar/short/long 等改为编译器内建短名。
This commit is contained in:
1 parent
8d27747c7c
commit
f19d25782f
66 files changed
+2445
-3638
No files matched your search
+28
-31
@@ -69,7 +69,7 @@ _HEX_ALPHABET: str = '0123456789abcdefABCDEF'
|
||||
#(内部标记 c.@CIf 族由解析期合成,不走此处)。
|
||||
_REMOVED_CIF_NAMES: frozenset[str] = frozenset({
|
||||
'CIf', 'CIfdef', 'CIfndef', 'CElif', 'CElse', 'CEndif',
|
||||
'c.CIf', 'c.CIfdef', 'c.CIfndef', 'c.CElif', 'c.CElse', 'c.CEndif',
|
||||
'CIf', 'CIfdef', 'CIfndef', 'CElif', 'CElse', 'CEndif',
|
||||
})
|
||||
|
||||
|
||||
@@ -110,9 +110,9 @@ class TokenStream:
|
||||
self._PeekCacheIdx: int = -1
|
||||
self._PeekCacheTok: Token | None = None
|
||||
# 类型注解解析模式:为 True 时 '*' / '**' 按 C 风格指针后缀处理
|
||||
# (int* → int | t.CPtr、int** → 嵌套两层),不按乘法/幂运算消费。
|
||||
# (int* → int | CPtr、int** → 嵌套两层),不按乘法/幂运算消费。
|
||||
self._InTypeAnnotation: bool = False
|
||||
# 下标实参嵌套层数:'[' 实参内是表达式位置(t.CArray[T, A * B] 的尺寸),
|
||||
# 下标实参嵌套层数:'[' 实参内是表达式位置(CArray[T, A * B] 的尺寸),
|
||||
# 此处的 '*' 在有右操作数时按乘法解析(见 _ParseTerm / _AtOperandAfterStarRun)。
|
||||
self._SubscriptArgs: int = 0
|
||||
# Tail token of the last consumed C-style pointer suffix ('*' / '**').
|
||||
@@ -463,13 +463,13 @@ class ExprParserMixin(TokenStream):
|
||||
op_type: type | None = None
|
||||
if tok.Type == OP:
|
||||
if tok.Value == '*' and self._AtPtrSuffix(left):
|
||||
# C 风格指针后缀('*' 一层);展开为 base | t.CPtr 后继续。
|
||||
# C 风格指针后缀('*' 一层);展开为 base | CPtr 后继续。
|
||||
left = self._ConsumePtrSuffix(left)
|
||||
continue
|
||||
if self._InTypeAnnotation and tok.Value == '*':
|
||||
# 注解模式:'*' 后已无操作数(']' / ',' / ')' / ':' / '=' / 行尾 / ';')
|
||||
# 时它是 C 风格指针后缀标记,交上方判据与 _ParseTypeAnnotation 统一消费;
|
||||
# 但下标实参内的尺寸表达式(t.CArray[T, A * B])'*' 后仍有操作数,
|
||||
# 但下标实参内的尺寸表达式(CArray[T, A * B])'*' 后仍有操作数,
|
||||
# 必须按乘法继续——否则下标收尾报 `expected ']'`。
|
||||
if not (self._SubscriptArgs > 0 and self._AtOperandAfterStarRun()):
|
||||
break
|
||||
@@ -535,7 +535,7 @@ class ExprParserMixin(TokenStream):
|
||||
tok: Token = self._Peek()
|
||||
if tok.Type == OP and tok.Value in ('*', '**') and self._AtPtrSuffixCall(node):
|
||||
# `T*(x)` / `T**(x)` 指针后缀强转:解析为 cast 调用(与
|
||||
# `(T | t.CPtr)(x)` 同形)。在 trailer 循环里消费,故其后的
|
||||
# `(T | CPtr)(x)` 同形)。在 trailer 循环里消费,故其后的
|
||||
# `.attr` / `[i]` / `(…)` 仍由本循环继续挂接(如
|
||||
# `ast.Attribute*(expr_root).value`)。
|
||||
node = self._ConsumePtrSuffixCall(node, start)
|
||||
@@ -628,7 +628,7 @@ class ExprParserMixin(TokenStream):
|
||||
|
||||
- `defined(NAME)`:仅 cif/celif 条件内合法(`self._InCIfCond`),
|
||||
desugar 为内部标记调用 `c.@CIfdef(NAME)`;其余位置 FailFast。
|
||||
- `c.CIf` / `c.CIfdef` / `c.CIfndef`(及裸名):已删除,FailFast 指向新语法。
|
||||
- `CIf` / `CIfdef` / `CIfndef`(及裸名):已删除,FailFast 指向新语法。
|
||||
"""
|
||||
callee: str = self._CallCalleeName(node.func)
|
||||
if callee in _REMOVED_CIF_NAMES:
|
||||
@@ -646,8 +646,7 @@ class ExprParserMixin(TokenStream):
|
||||
f"'defined' expects exactly one macro name (e.g. defined(MAX_SIZE)), "
|
||||
f"at line {start.Line}")
|
||||
marker: N.Call = N.Call(
|
||||
func=N.Attribute(value=N.Name(id='c', ctx=N.Load()),
|
||||
attr='@CIfdef', ctx=N.Load()),
|
||||
func=N.Name(id='CIfdef', ctx=N.Load()),
|
||||
args=[node.args[0]], keywords=[])
|
||||
self._FixLoc(marker, start)
|
||||
return marker
|
||||
@@ -666,8 +665,8 @@ class ExprParserMixin(TokenStream):
|
||||
def _ParseSliceList(self) -> N.AST:
|
||||
"""解析下标列表:a[1] / a[1:2] / a[1:2:3] / a[1,2] / a[...] / a[::]
|
||||
|
||||
下标实参内是**表达式**位置(如 `t.CArray[T, A * B]` 的尺寸),此处的 '*'
|
||||
应按乘法解析;同时 `t.CArray[str*, 4]` 的指针后缀仍要成立——两者由
|
||||
下标实参内是**表达式**位置(如 `CArray[T, A * B]` 的尺寸),此处的 '*'
|
||||
应按乘法解析;同时 `CArray[str*, 4]` 的指针后缀仍要成立——两者由
|
||||
`_AtOperandAfterStarRun`('*' 后是否还有操作数)区分,故此处登记已进入实参。
|
||||
"""
|
||||
self._SubscriptArgs += 1
|
||||
@@ -1301,7 +1300,7 @@ class ExprParserMixin(TokenStream):
|
||||
first: N.expr = self.ParseExpr()
|
||||
# Paren-less C cast `(T*)x`: the inner expression ends with a pointer suffix
|
||||
# (_Prev() is that suffix's tail token) and the operand follows ')'. Same
|
||||
# product as `(T*)(x)` / `T*(x)`: a Call whose func is `T | t.CPtr`.
|
||||
# product as `(T*)(x)` / `T*(x)`: a Call whose func is `T | CPtr`.
|
||||
is_ptr_cast: bool = self._PtrSuffixTail is not None and self._AtOp(')') and self._Prev() is self._PtrSuffixTail
|
||||
self._SkipNL()
|
||||
# 生成器表达式 (x for ...)
|
||||
@@ -1692,8 +1691,8 @@ class ExprParserMixin(TokenStream):
|
||||
注解模式开启后,'_ParseTerm'/'_ParsePower' 不再把 '*' / '**' 当
|
||||
乘法/幂运算消费,而由本方法统一循环消费并展开为嵌套联合类型:
|
||||
|
||||
int* → int | t.CPtr (i32*)
|
||||
int** → (int | t.CPtr) | t.CPtr (i32**)
|
||||
int* → int | CPtr (i32*)
|
||||
int** → (int | CPtr) | CPtr (i32**)
|
||||
int****** → 6 层嵌套 (i32******)
|
||||
|
||||
展开为 BinOp(BitOr) 链后,TPC/VPC 现有类型解析(TypeAnnotationResolver
|
||||
@@ -1702,11 +1701,11 @@ class ExprParserMixin(TokenStream):
|
||||
|
||||
无法解析的后缀形态**响亮失败**(SyntaxError,含 行:列 + 源码片段 + 形态 +
|
||||
正确写法示例),绝不静默丢弃:注解末尾若仍遗留未被 `_AtPtrSuffix` 接受的
|
||||
'*'/'**'(如 `a: int * 2` / `a: int* | t.CPtr`),判据拒绝消费即终止编译
|
||||
'*'/'**'(如 `a: int * 2` / `a: int* | CPtr`),判据拒绝消费即终止编译
|
||||
(历史事故:静默退化会产出错误的指针层数)。
|
||||
|
||||
值引用参数注解(仅形参位有效):前导 `&` 为 ref 模式、`&temp` 为 temp 模式,
|
||||
合成联合形态 `T | t.CRef` / `T | t.CTempRef` 承载(CRef/CTempRef 非真实类,
|
||||
合成联合形态 `T | CRef` / `T | CTempRef` 承载(CRef/CTempRef 非真实类,
|
||||
仅按名字识别;语义侧见 HandlesFunctions / FuncGen)。表达式位的 `&x` 不受影响。
|
||||
"""
|
||||
ref_mode: str | None = None
|
||||
@@ -1757,9 +1756,9 @@ class ExprParserMixin(TokenStream):
|
||||
f"{tok.Value!r} 前面不是可加后缀的类型(Name / Attribute / Subscript),"
|
||||
f"或其后不是后缀的合法结束位置(注解结尾,或 ']' / ',' / ')' / ':' / '=')。"
|
||||
f"源码片段 {snippet!r}。"
|
||||
f"期望形态:`T*`(1 层)/ `T**`(2 层),T 可为裸名 / t.X / mod.Type / "
|
||||
f"rawptr[T] / t.CPtr[T]。"
|
||||
f"正确示例:`a: t.CPtr*` / `a: rawptr*` / `a: t.X**` / "
|
||||
f"期望形态:`T*`(1 层)/ `T**`(2 层),T 可为裸名 / X / mod.Type / "
|
||||
f"rawptr[T] / CPtr[T]。"
|
||||
f"正确示例:`a: CPtr*` / `a: rawptr*` / `a: X**` / "
|
||||
f"`a: rawptr[ast.AST*]` / `def f(p: int*) -> int**`。"
|
||||
)
|
||||
if ref_mode is not None:
|
||||
@@ -1767,13 +1766,12 @@ class ExprParserMixin(TokenStream):
|
||||
return expr
|
||||
|
||||
def _MakeRefMarker(self, base: N.expr, mode: str, tok: Token) -> N.expr:
|
||||
"""构造值引用标记联合:`base | t.CRef`(ref)/ `base | t.CTempRef`(temp)。
|
||||
"""构造值引用标记联合:`base | CRef`(ref)/ `base | CTempRef`(temp)。
|
||||
|
||||
CRef / CTempRef 非真实类,仅作为注解 AST 内的名字标记(语义侧按名字识别)。
|
||||
"""
|
||||
marker: N.expr = N.Attribute(
|
||||
value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='CRef' if mode == 'ref' else 'CTempRef',
|
||||
marker: N.expr = N.Name(
|
||||
id='CRef' if mode == 'ref' else 'CTempRef',
|
||||
ctx=N.Load())
|
||||
node: N.BinOp = N.BinOp(left=base, op=N.BitOr(), right=marker)
|
||||
self._FixLoc(node, tok)
|
||||
@@ -1796,7 +1794,7 @@ class ExprParserMixin(TokenStream):
|
||||
|
||||
判据(两条同时成立):
|
||||
1. base 是"类型原子"形态(Name / Attribute / Subscript)—— 即 ``ast.AST``、
|
||||
``t.CArray[X, N]``、``rawptr[X]`` 之类;
|
||||
``CArray[X, N]``、``rawptr[X]`` 之类;
|
||||
2. 该 '*'/'**' 串(可跨括号内换行 NL)之后紧跟"无右操作数"位置:
|
||||
``]`` / ``,`` / ``)`` / ``:`` / ``=``(全局),或注解模式下的
|
||||
NEWLINE / NL / ENDMARKER / ``;``。
|
||||
@@ -1830,7 +1828,7 @@ class ExprParserMixin(TokenStream):
|
||||
return False
|
||||
|
||||
def _ConsumePtrSuffix(self, expr: N.expr) -> N.expr:
|
||||
"""消费连续的 C 风格指针后缀('*' 一层 / '**' 两层),展开为 base | t.CPtr 链。"""
|
||||
"""消费连续的 C 风格指针后缀('*' 一层 / '**' 两层),展开为 base | CPtr 链。"""
|
||||
while True:
|
||||
tok: Token = self._Peek()
|
||||
if tok.Type == OP and tok.Value == '*':
|
||||
@@ -1864,7 +1862,7 @@ class ExprParserMixin(TokenStream):
|
||||
与 `_AtPtrSuffix` 互补:后者判「'*' 后是无右操作数位置」(']' / ',' / ')' /
|
||||
':' / '=' / 行尾 / ';' ⇒ 指针后缀),本方法判其反面('*' 后是 NAME / NUMBER /
|
||||
STRING / FSTRING 或 '(' / '[' / '{' / 一元前缀 ⇒ 乘法)。用于下标实参内区分
|
||||
`t.CArray[T, A * B]`(乘法)与 `t.CArray[T*, 4]`(指针后缀)。
|
||||
`CArray[T, A * B]`(乘法)与 `CArray[T*, 4]`(指针后缀)。
|
||||
"""
|
||||
j: int = 0
|
||||
while True:
|
||||
@@ -1923,17 +1921,16 @@ class ExprParserMixin(TokenStream):
|
||||
def _ConsumePtrSuffixCall(self, base: N.expr, start: Token) -> N.expr:
|
||||
"""把已认定为 `T*(...)` 的指针后缀强转解析为**调用**。
|
||||
|
||||
产物与既有强转形态 `(T | t.CPtr)(...)` 逐字同形:同为 `ast.Call`
|
||||
(func = `T` 展开的 `base | t.CPtr` 链,args/keywords = 括号实参),
|
||||
产物与既有强转形态 `(T | CPtr)(...)` 逐字同形:同为 `ast.Call`
|
||||
(func = `T` 展开的 `base | CPtr` 链,args/keywords = 括号实参),
|
||||
不新造第二套 cast 表示。
|
||||
"""
|
||||
func: N.expr = self._ConsumePtrSuffix(base)
|
||||
return self._ParseCallTail(func, start)
|
||||
|
||||
def _MakePtrType(self, base: N.expr, tok: Token) -> N.expr:
|
||||
"""构造一层指针包装:base | t.CPtr。"""
|
||||
cptr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='CPtr', ctx=N.Load())
|
||||
"""构造一层指针包装:base | CPtr。"""
|
||||
cptr: N.expr = N.Name(id='CPtr', ctx=N.Load())
|
||||
node: N.BinOp = N.BinOp(left=base, op=N.BitOr(), right=cptr)
|
||||
self._FixLoc(node, tok)
|
||||
return node
|
||||
+58
-68
@@ -28,8 +28,8 @@ from lib.vast.Tokenizer import (
|
||||
# 语法:`virtual class` / `novirtual class` / `virtual def` / `novirtual def`
|
||||
# (修饰符写在 class/def **之前**,允许与修饰对象同行,也允许各占一行)。
|
||||
#
|
||||
# 语义:与既有装饰器**同一套表示**——virtual → `@t.CVTable`,
|
||||
# novirtual → `@t.NoVTable`。本层只"合成装饰器节点",不新增第二套表示:
|
||||
# 语义:与既有装饰器**同一套表示**——virtual → `@CVTable`,
|
||||
# novirtual → `@NoVTable`。本层只"合成装饰器节点",不新增第二套表示:
|
||||
# - 类级:CVTable 强制有 vtable / NoVTable 强制无 vtable
|
||||
# (TPC:HandlesClassDef._resolve_class_flags 读 ClassDef.decorator_list
|
||||
# 的 CVTable/NoVTable;VPC:ClassGenBase._detect_vtable_status)
|
||||
@@ -62,7 +62,7 @@ _VIRTUAL_EXAMPLE: str = (
|
||||
'novirtual class B: novirtual def helper(self) -> int: ...'
|
||||
)
|
||||
|
||||
# tls 修饰符(软关键字):`tls def f(...)` ⇒ 合成既有装饰器 `@t.TLS`
|
||||
# tls 修饰符(软关键字):`tls def f(...)` ⇒ 合成既有装饰器 `@TLS`
|
||||
#(一次性初始化守卫,见 HandlesFunctions 的 TLS 分支)。与 virtual/novirtual 同一套
|
||||
# "软关键字 + 合成既有装饰器"表示,不新增第二套语义;只在语句起始且后随 def 时生效,
|
||||
# 故 `tls: local = local()` / `tls.set(...)` 等把 tls 当标识符的写法逐字不变。
|
||||
@@ -75,8 +75,8 @@ _TLS_KEYWORD: str = 'tls'
|
||||
# 语义(用户 2026-10-01 定):与 class 同形,但**只能表示数据类型**:
|
||||
# - 禁止 virtual / novirtual 修饰(见 _ParseVirtualModified 的显式拦截);
|
||||
# - 禁止类体内定义 def(见 _ParseStructDef 的 fail-fast);
|
||||
# - 解析期合成 `@t.NoVTable` 装饰器 + 追加 `t.CStruct` 标记基类,
|
||||
# 与手写 `@t.NoVTable class X(t.CStruct):` 逐字段同形 ⇒ 下游
|
||||
# - 解析期合成 `@NoVTable` 装饰器 + 追加 `CStruct` 标记基类,
|
||||
# 与手写 `@NoVTable class X(CStruct):` 逐字段同形 ⇒ 下游
|
||||
# (HandlesClassDef._resolve_class_flags / _MARKER_BASES)零新增判据。
|
||||
# - 允许出现在 REnum 内部(REnum 变体本就是嵌套 ClassDef),也允许 struct 内
|
||||
# 再写 struct(与 class 内写 class 同口径)。
|
||||
@@ -93,7 +93,7 @@ _STRUCT_EXAMPLE: str = (
|
||||
# 解析时 desugar 为 is_switch=True 的 N.Match。
|
||||
_SWITCH_KEYWORD: str = 'switch'
|
||||
|
||||
# fallthrough 关键字(硬):仅在 switch 的 case 体内合法,脱糖为 `c.NoBreak()`
|
||||
# fallthrough 关键字(硬):仅在 switch 的 case 体内合法,脱糖为 `NoBreak()`
|
||||
# 标记调用(switch 生成侧据此让 case 体不自动跳出 switch,落到下一个 case)。
|
||||
_FALLTHROUGH_KEYWORD: str = 'fallthrough'
|
||||
|
||||
@@ -107,13 +107,13 @@ _FALLTHROUGH_KEYWORD: str = 'fallthrough'
|
||||
# celif E: → 同链下一个 If(test=c.@CIf(E), ...)(挂在上一支 orelse)
|
||||
# celse: → 普通 orelse
|
||||
# defined(N) → c.@CIfdef(N) 标记调用
|
||||
# 标记(c.@CIf / c.@CIfdef)是内部表示:用户写 c.CIf(...) 在 ExprParser 处报错。
|
||||
# 标记(c.@CIf / c.@CIfdef)是内部表示:用户写 CIf(...) 在 ExprParser 处报错。
|
||||
_CIF_KEYWORD: str = 'cif'
|
||||
_CELIF_KEYWORD: str = 'celif'
|
||||
_CELSE_KEYWORD: str = 'celse'
|
||||
# 内部 CIf 族标记:desugar 产出的调用名(用户不可写)。
|
||||
# 与 Viper 侧解析器(includes/ast/parser.vp 的 _MakeCifMarker)同拼写:属性名带前导 '@',
|
||||
# 词法器无法产出该拼写,故用户写的 c.CIf(...) 永远不会命中此标记(会被 ExprParser 拒绝)。
|
||||
# 词法器无法产出该拼写,故用户写的 CIf(...) 永远不会命中此标记(会被 ExprParser 拒绝)。
|
||||
_CIF_MARKER: str = '@CIf'
|
||||
_CIFDEF_MARKER: str = '@CIfdef'
|
||||
# cif 语句起始判定:语句起始 NAME('cif') 后紧跟这些运算符时按普通语句(赋值/注解)
|
||||
@@ -166,10 +166,10 @@ class Parser(ExprParserMixin):
|
||||
tok: Token = self._Peek()
|
||||
if tok.Type == NAME:
|
||||
v: str = tok.Value
|
||||
# extern 函数声明(FFI,等价 t.State)——必须在软关键字 def 分派之前
|
||||
# extern 函数声明(FFI,等价 State)——必须在软关键字 def 分派之前
|
||||
if v == 'extern':
|
||||
return self._ParseExternDef()
|
||||
# export 函数声明(等价 t.CExport,裸名导出不增加 SHA1 头)——
|
||||
# export 函数声明(等价 CExport,裸名导出不增加 SHA1 头)——
|
||||
# 必须在软关键字 def 分派之前
|
||||
if v == 'export':
|
||||
return self._ParseExportDef()
|
||||
@@ -177,25 +177,25 @@ class Parser(ExprParserMixin):
|
||||
# 仅 `static def 名字` 形态判定为函数定义——判据必须同时要求第二个 token
|
||||
# 是 `def`,故 `static = 5` / `static x = 5` 不会被误吃成函数定义。
|
||||
# 变量形式 `static 名字: 类型 = 值` 不在本层处理,由 SymbolUtils 的前置
|
||||
# 修饰符展开统一脱糖为 `名字: t.CStatic | 类型 = 值`。
|
||||
# 修饰符展开统一脱糖为 `名字: CStatic | 类型 = 值`。
|
||||
if (v == 'static' and self._Peek(1).Type == NAME
|
||||
and self._Peek(1).Value == 'def'):
|
||||
return self._ParseStaticDef()
|
||||
# define 宏函数定义(与 def 语义一致,返回注解自动追加 t.CDefine
|
||||
# define 宏函数定义(与 def 语义一致,返回注解自动追加 CDefine
|
||||
# 标记为宏函数;软关键字:仅"define + 标识符"形态才判定为函数定义,
|
||||
# 变量名/调用(define = 5、define(x))不受影响)——必须在软关键字
|
||||
# def 分派之前
|
||||
if v == 'define' and self._Peek(1).Type == NAME:
|
||||
return self._ParseDefineDef()
|
||||
# virtual / novirtual 修饰符(软关键字):只在"语句起始 + 紧跟 class/def"
|
||||
# 时生效,合成既有装饰器 @t.CVTable / @t.NoVTable(见 _ParseVirtualModified)。
|
||||
# 时生效,合成既有装饰器 @CVTable / @NoVTable(见 _ParseVirtualModified)。
|
||||
# 放在 def/class 分派之前:修饰符必须先被消费,class/def 才能照常分派。
|
||||
# 与软关键字 fn→def 的先后关系:`.vp` 源码在进入本解析器之前已过
|
||||
# SymbolUtils.ExpandSoftKeywords(fn/fun/func/function → def),
|
||||
# 故 `virtual fn m()` 在此已是 `virtual def m()`;本层只认 class/def。
|
||||
if v in _VIRTUAL_MARKERS:
|
||||
return self._ParseVirtualModified()
|
||||
# tls 修饰符(软关键字):语句起始 + 紧跟 def 时生效,合成既有装饰器 @t.TLS。
|
||||
# tls 修饰符(软关键字):语句起始 + 紧跟 def 时生效,合成既有装饰器 @TLS。
|
||||
if v == _TLS_KEYWORD and self._IsTlsDefStart():
|
||||
return self._ParseTlsModified()
|
||||
# 软关键字函数定义:fn/fun/func/function + 标识符
|
||||
@@ -242,7 +242,7 @@ class Parser(ExprParserMixin):
|
||||
if v == _SWITCH_KEYWORD:
|
||||
return self._ParseSwitch()
|
||||
# fallthrough 关键字(硬):仅在 switch 的 case 体内合法,脱糖为
|
||||
# `c.NoBreak()` 标记调用,由 switch 生成侧消费(case 体因此不自动
|
||||
# `NoBreak()` 标记调用,由 switch 生成侧消费(case 体因此不自动
|
||||
# 跳出 switch)。合法位置由生成侧判定:写进 match 或 switch 之外
|
||||
# 一律 FailFastError。
|
||||
if v == _FALLTHROUGH_KEYWORD:
|
||||
@@ -289,7 +289,7 @@ class Parser(ExprParserMixin):
|
||||
# fallthrough 关键字(语句级)
|
||||
# ==================================================================
|
||||
def _ParseFallThrough(self) -> N.stmt:
|
||||
"""`fallthrough` 脱糖为 `c.NoBreak()`(switch 生成侧识别的 fallthrough 标记)
|
||||
"""`fallthrough` 脱糖为 `NoBreak()`(switch 生成侧识别的 fallthrough 标记)
|
||||
|
||||
合法位置只有 switch 的 case 体;写进 match 或 switch 之外由生成侧
|
||||
(HandlesMatch / HandlesBody)fail-fast。
|
||||
@@ -297,8 +297,7 @@ class Parser(ExprParserMixin):
|
||||
tok: Token = self._Peek()
|
||||
self._Next()
|
||||
marker: N.Call = N.Call(
|
||||
func=N.Attribute(value=N.Name(id='c', ctx=N.Load()),
|
||||
attr='NoBreak', ctx=N.Load()),
|
||||
func=N.Name(id='NoBreak', ctx=N.Load()),
|
||||
args=[], keywords=[])
|
||||
node: N.Expr = N.Expr(value=marker)
|
||||
self._FixLoc(node, tok)
|
||||
@@ -423,9 +422,9 @@ class Parser(ExprParserMixin):
|
||||
|
||||
@staticmethod
|
||||
def _IsCTypedefAnnotation(annotation: N.expr | None) -> bool:
|
||||
"""注解是否为 typedef 标记(裸 `CTypedef` / `t.CTypedef` / 含它的 `|` 联合)。
|
||||
"""注解是否为 typedef 标记(裸 `CTypedef` / `CTypedef` / 含它的 `|` 联合)。
|
||||
|
||||
用于把 typedef 的右值按**类型位置**解析(`X: t.CTypedef = const uint16*`
|
||||
用于把 typedef 的右值按**类型位置**解析(`X: CTypedef = const uint16*`
|
||||
里的 `*` 后缀由 _ParseTypeAnnotation 消费,与注解位同一规则;描述符
|
||||
`const`/`volatile` 已由 SymbolUtils._ExpandTypeDescriptors 在文本层展开)。
|
||||
仅按标记名判定,不依赖 import 别名表(与 VPC `_IsCTypedefAnnotation` 同口径)。
|
||||
@@ -447,7 +446,7 @@ class Parser(ExprParserMixin):
|
||||
注意:仅当目标为简单 Name/Attribute/Subscript 且后随 ':' 时匹配;
|
||||
元组/列表解包不做注解(返回 None 走普通路径)。
|
||||
|
||||
`t.CTypedef` 注解的右值是**类型**而非一般表达式(`const str` / `uint16*`),
|
||||
`CTypedef` 注解的右值是**类型**而非一般表达式(`const str` / `uint16*`),
|
||||
故走 `_ParseTypeAnnotation`(与注解位同一路径,支持 C 式指针后缀)。
|
||||
"""
|
||||
start: Token = self._Peek()
|
||||
@@ -725,7 +724,7 @@ class Parser(ExprParserMixin):
|
||||
# `@deco` 与 `virtual class`/`virtual def` 组合:合成标记追加在既有装饰器之后
|
||||
return self._ParseVirtualModified(decorators=decorator_list)
|
||||
if tok.Type == NAME and tok.Value == _TLS_KEYWORD and self._IsTlsDefStart():
|
||||
# `@deco` 与 `tls def` 组合:合成 @t.TLS 追加在既有装饰器之后
|
||||
# `@deco` 与 `tls def` 组合:合成 @TLS 追加在既有装饰器之后
|
||||
return self._ParseTlsModified(decorators=decorator_list)
|
||||
raise SyntaxError(f"decorator must be followed by def/class, got {tok.Value!r}")
|
||||
|
||||
@@ -760,9 +759,9 @@ class Parser(ExprParserMixin):
|
||||
def _ParseVirtualModified(self, decorators: list[N.expr] | None = None) -> N.stmt:
|
||||
"""`virtual class` / `novirtual class` / `virtual def` / `novirtual def`。
|
||||
|
||||
合成 `@t.CVTable` / `@t.NoVTable` 装饰器后交给 _ParseClassDef /
|
||||
合成 `@CVTable` / `@NoVTable` 装饰器后交给 _ParseClassDef /
|
||||
_ParseFunctionDef,产出与**手写同名装饰器**逐字段同形的 AST
|
||||
(decorator_list 多一个 Attribute(Name('t', Load), 'CVTable'|'NoVTable', Load)),
|
||||
(decorator_list 多一个 Name('CVTable'|'NoVTable', Load)),
|
||||
故下游(_resolve_class_flags / _should_method_be_virtual 同族判据)零新增分支。
|
||||
|
||||
非法形态**响亮失败**(不静默丢修饰符):
|
||||
@@ -786,7 +785,7 @@ class Parser(ExprParserMixin):
|
||||
# 单独报文(而不是落到通用"后随非 class/def")以便直接给出修法。
|
||||
raise self._StructSyntaxError(
|
||||
f'{mod.Value} struct 非法:struct 禁止 virtual/novirtual 修饰', mod,
|
||||
'struct 天然无虚表(解析期已合成 @t.NoVTable),请直接写 `struct X:`;'
|
||||
'struct 天然无虚表(解析期已合成 @NoVTable),请直接写 `struct X:`;'
|
||||
'需要虚表语义请改用 class。')
|
||||
raise self._VirtualSyntaxError(
|
||||
f"{mod.Value!r} 后随 {nxt_text}(非 class/def)", mod,
|
||||
@@ -799,8 +798,7 @@ class Parser(ExprParserMixin):
|
||||
f'{mod.Value} def 描述的是「类体内方法的虚/非虚」,'
|
||||
f'模块级 / 函数体 / 分支体内没有可归属的类。')
|
||||
self._Next() # 消费修饰符
|
||||
deco: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr=marker, ctx=N.Load())
|
||||
deco: N.expr = N.Name(id=marker, ctx=N.Load())
|
||||
self._FixLoc(deco, mod)
|
||||
deco_list: list[N.expr] = list(decorators or [])
|
||||
deco_list.append(deco)
|
||||
@@ -824,16 +822,15 @@ class Parser(ExprParserMixin):
|
||||
return False
|
||||
|
||||
def _ParseTlsModified(self, decorators: list[N.expr] | None = None) -> N.stmt:
|
||||
"""`tls def f(...)`:消费 tls,合成 `@t.TLS` 后交给 _ParseFunctionDef。
|
||||
"""`tls def f(...)`:消费 tls,合成 `@TLS` 后交给 _ParseFunctionDef。
|
||||
|
||||
与手写 `@t.TLS` 逐字段同形(decorator_list 追加
|
||||
Attribute(Name('t', Load), 'TLS', Load)),故下游一次性初始化的守卫生成路径
|
||||
与手写 `@TLS` 逐字段同形(decorator_list 追加
|
||||
Name('TLS', Load)),故下游一次性初始化的守卫生成路径
|
||||
(HandlesFunctions 的 TLS 分支)零新增判据。tls 对方法与模块级函数同样生效。
|
||||
"""
|
||||
mod: Token = self._Peek() # tls
|
||||
self._Next() # 消费修饰符
|
||||
deco: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='TLS', ctx=N.Load())
|
||||
deco: N.expr = N.Name(id='TLS', ctx=N.Load())
|
||||
self._FixLoc(deco, mod)
|
||||
deco_list: list[N.expr] = list(decorators or [])
|
||||
deco_list.append(deco)
|
||||
@@ -852,7 +849,7 @@ class Parser(ExprParserMixin):
|
||||
f"[TPC] struct 定义非法({detail}):行 {tok.Line} 列 {tok.Col},"
|
||||
f"源码片段 {self._SourceLine(tok.Line).strip()!r}。"
|
||||
f"struct 与 class 同形,但**只能表示数据类型**:"
|
||||
f"① 禁止 virtual / novirtual 修饰(struct 天然无虚表,已内置 @t.NoVTable);"
|
||||
f"① 禁止 virtual / novirtual 修饰(struct 天然无虚表,已内置 @NoVTable);"
|
||||
f"② 禁止在 struct 内定义 def(需要方法请改用 class);"
|
||||
f"③ 允许在 REnum 内作为变体、也允许 struct 内再写 struct。"
|
||||
f"正确示例:{_STRUCT_EXAMPLE}。"
|
||||
@@ -862,28 +859,26 @@ class Parser(ExprParserMixin):
|
||||
)
|
||||
|
||||
def _ParseStructDef(self, decorators: list[N.expr] | None = None) -> N.ClassDef:
|
||||
"""`struct X:` / `struct X(Base):` → 与 `@t.NoVTable class X(t.CStruct):`
|
||||
"""`struct X:` / `struct X(Base):` → 与 `@NoVTable class X(CStruct):`
|
||||
逐字段同形的 ClassDef(与 VPC 的 _parse_structdef 同口径)。
|
||||
|
||||
实现:复用 _ParseClassDef 的完整解析路径(类型参数 / 基类 / 关键字实参 /
|
||||
类体套件),只在**解析前后**补三件事:
|
||||
· 解析前把合成的 `@t.NoVTable` 追加进装饰器列表(与 virtual/novirtual
|
||||
· 解析前把合成的 `@NoVTable` 追加进装饰器列表(与 virtual/novirtual
|
||||
同款表示)⇒ 类级强制无虚表,即使父类带虚表;
|
||||
· 解析后把 `t.CStruct` 标记基类**追加**到 bases 末尾(不提位用户基类,
|
||||
· 解析后把 `CStruct` 标记基类**追加**到 bases 末尾(不提位用户基类,
|
||||
真实父类解析顺序不变)⇒ 数据类语义(_MARKER_BASES 认它,不当真实父类);
|
||||
· 解析后校验类体**直接子节点**里没有 def —— struct 只能表示数据类型。
|
||||
_ParseClassDef 的首个 `_Next()` 消费的正是 `struct` 关键字本身,故本函数
|
||||
不预先消费,行号/列号与写法均继承自该 token。
|
||||
"""
|
||||
start: Token = self._Peek() # struct(由 _ParseClassDef 的 _Next() 消费)
|
||||
deco: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='NoVTable', ctx=N.Load())
|
||||
deco: N.expr = N.Name(id='NoVTable', ctx=N.Load())
|
||||
self._FixLoc(deco, start)
|
||||
deco_list: list[N.expr] = list(decorators or [])
|
||||
deco_list.append(deco)
|
||||
node: N.ClassDef = self._ParseClassDef(decorators=deco_list)
|
||||
marker_base: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='CStruct', ctx=N.Load())
|
||||
marker_base: N.expr = N.Name(id='CStruct', ctx=N.Load())
|
||||
self._FixLoc(marker_base, start)
|
||||
node.bases.append(marker_base)
|
||||
for item in node.body:
|
||||
@@ -926,7 +921,7 @@ class Parser(ExprParserMixin):
|
||||
return node
|
||||
|
||||
def _ParseExternDef(self, decorators: list[N.expr] | None = None) -> N.FunctionDef:
|
||||
"""解析 extern 函数声明(FFI,与 t.State 作用相当)。
|
||||
"""解析 extern 函数声明(FFI,与 State 作用相当)。
|
||||
|
||||
允许语法(均声明不定义,不生成函数体):
|
||||
extern def A(x: int) -> int: pass
|
||||
@@ -934,7 +929,7 @@ class Parser(ExprParserMixin):
|
||||
extern def A(x: int) -> int
|
||||
extern A(x: int) -> int
|
||||
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | t.State``
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | State``
|
||||
以复用 TPC 的 IsState 路径;并设自定义属性 ``Extern = True``
|
||||
供 Unparser 还原 extern 语法。
|
||||
"""
|
||||
@@ -960,9 +955,8 @@ class Parser(ExprParserMixin):
|
||||
type_comment=None, type_params=type_params,
|
||||
)
|
||||
node.Extern = True
|
||||
# 返回注解改写为 <原类型> | t.State,使 TPC 识别为 State 函数(仅声明)
|
||||
state_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='State', ctx=N.Load())
|
||||
# 返回注解改写为 <原类型> | State,使 TPC 识别为 State 函数(仅声明)
|
||||
state_attr: N.expr = N.Name(id='State', ctx=N.Load())
|
||||
if returns is not None:
|
||||
node.returns = N.BinOp(left=returns, op=N.BitOr(), right=state_attr)
|
||||
else:
|
||||
@@ -971,7 +965,7 @@ class Parser(ExprParserMixin):
|
||||
return node
|
||||
|
||||
def _ParseExportDef(self, decorators: list[N.expr] | None = None) -> N.FunctionDef:
|
||||
"""解析 export 函数声明(等价 t.CExport,导出裸名、不加模块 SHA1 头)。
|
||||
"""解析 export 函数声明(等价 CExport,导出裸名、不加模块 SHA1 头)。
|
||||
|
||||
允许语法(与 extern 对称,配不配 def 都一样):
|
||||
export def A(x: int) -> int: pass
|
||||
@@ -979,7 +973,7 @@ class Parser(ExprParserMixin):
|
||||
export def A(x: int) -> int
|
||||
export A(x: int) -> int
|
||||
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | t.CExport``
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | CExport``
|
||||
以复用 TPC 的 CExport 路径(符号名不增加 SHA1 前缀);并设自定义
|
||||
属性 ``Export = True`` 供 Unparser 还原 export 语法。
|
||||
"""
|
||||
@@ -1005,10 +999,9 @@ class Parser(ExprParserMixin):
|
||||
type_comment=None, type_params=type_params,
|
||||
)
|
||||
node.Export = True
|
||||
# 返回注解改写为 <原类型> | t.CExport,使 TPC 识别为 CExport 函数
|
||||
# 返回注解改写为 <原类型> | CExport,使 TPC 识别为 CExport 函数
|
||||
# (导出裸名,不增加模块 SHA1 头;有条件情况下导出)
|
||||
export_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='CExport', ctx=N.Load())
|
||||
export_attr: N.expr = N.Name(id='CExport', ctx=N.Load())
|
||||
if returns is not None:
|
||||
node.returns = N.BinOp(left=returns, op=N.BitOr(), right=export_attr)
|
||||
else:
|
||||
@@ -1017,7 +1010,7 @@ class Parser(ExprParserMixin):
|
||||
return node
|
||||
|
||||
def _ParseStaticDef(self, decorators: list[N.expr] | None = None) -> N.FunctionDef:
|
||||
"""解析 static 函数定义(等价 ``@t.CStatic``,与 ViperC 的
|
||||
"""解析 static 函数定义(等价 ``@CStatic``,与 ViperC 的
|
||||
`_ParseStaticModified` 同源)。
|
||||
|
||||
允许语法(与 export/extern 对称,配不配 def 都一样):
|
||||
@@ -1025,11 +1018,11 @@ class Parser(ExprParserMixin):
|
||||
static A(x: int) -> int: ...
|
||||
|
||||
与 export/extern 的**两处不同**:
|
||||
- **不改写返回注解**(不追加 `| t.CStatic` / `| t.State`):CStatic 是
|
||||
- **不改写返回注解**(不追加 `| CStatic` / `| State`):CStatic 是
|
||||
函数属性,由下面的合成装饰器承载,返回类型语义逐字不变;
|
||||
- **合成 `@t.CStatic` 装饰器**追加在既有装饰器之后,产出与**手写
|
||||
`@t.CStatic`** 逐字段同形(decorator_list 多一个
|
||||
Attribute(Name('t', Load), 'CStatic', Load)),下游零新增判据。
|
||||
- **合成 `@CStatic` 装饰器**追加在既有装饰器之后,产出与**手写
|
||||
`@CStatic`** 逐字段同形(decorator_list 多一个
|
||||
Name('CStatic', Load)),下游零新增判据。
|
||||
|
||||
另设自定义属性 ``Static = True`` 供 Unparser 还原 static 语法
|
||||
(镜像 Extern/Export;因 FunctionDef 的 __slots__ 槽位未含 Static 且
|
||||
@@ -1051,9 +1044,8 @@ class Parser(ExprParserMixin):
|
||||
if self._AtOp(':'):
|
||||
self._Next()
|
||||
body = self._ParseSuite()
|
||||
# 合成 @t.CStatic 装饰器(追加在既有装饰器之后)
|
||||
static_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='CStatic', ctx=N.Load())
|
||||
# 合成 @CStatic 装饰器(追加在既有装饰器之后)
|
||||
static_attr: N.expr = N.Name(id='CStatic', ctx=N.Load())
|
||||
self._FixLoc(static_attr, start)
|
||||
deco_list: list[N.expr] = list(decorators or [])
|
||||
deco_list.append(static_attr)
|
||||
@@ -1066,7 +1058,7 @@ class Parser(ExprParserMixin):
|
||||
# 注:FunctionDef 是 __slots__ 类(见 vast/Nodes.py 的 _FUNC_ATTRS,当前槽位
|
||||
# 为 Extern/Export/Define,未含 Static)——补槽位需改第三个文件(本次不许可),
|
||||
# 故仅在槽位存在时设置,避免 AttributeError 中断解析;下游对 static 函数的
|
||||
# 识别靠上面合成的 @t.CStatic 装饰器(HandlesFunctions 的存储类装饰器分支),
|
||||
# 识别靠上面合成的 @CStatic 装饰器(HandlesFunctions 的存储类装饰器分支),
|
||||
# 与 virtual/novirtual 仅合成装饰器同构。
|
||||
if hasattr(type(node), 'Static'):
|
||||
node.Static = True
|
||||
@@ -1080,8 +1072,8 @@ class Parser(ExprParserMixin):
|
||||
define A(x: int) -> int: ...
|
||||
define A(x: int): ...
|
||||
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | t.CDefine``
|
||||
(无显式返回注解时单独 ``t.CDefine``),使 TPC/VPC 复用既有的
|
||||
产出标准 FunctionDef 节点,返回注解改写为 ``<原类型> | CDefine``
|
||||
(无显式返回注解时单独 ``CDefine``),使 TPC/VPC 复用既有的
|
||||
CDefine 宏函数识别路径(StubGen 原样保留生成 C #define、
|
||||
alwaysinline 内联);并设自定义属性 ``Define = True`` 供
|
||||
Unparser 还原 define 语法。
|
||||
@@ -1104,10 +1096,9 @@ class Parser(ExprParserMixin):
|
||||
type_comment=None, type_params=type_params,
|
||||
)
|
||||
node.Define = True
|
||||
# 返回注解改写为 <原类型> | t.CDefine,使下游识别为宏函数
|
||||
# 返回注解改写为 <原类型> | CDefine,使下游识别为宏函数
|
||||
# (StubGen 保留原样输出 C #define;TPC 标记 alwaysinline 内联)
|
||||
define_attr: N.expr = N.Attribute(value=N.Name(id='t', ctx=N.Load()),
|
||||
attr='CDefine', ctx=N.Load())
|
||||
define_attr: N.expr = N.Name(id='CDefine', ctx=N.Load())
|
||||
if returns is not None:
|
||||
node.returns = N.BinOp(left=returns, op=N.BitOr(), right=define_attr)
|
||||
else:
|
||||
@@ -1298,7 +1289,7 @@ class Parser(ExprParserMixin):
|
||||
return node
|
||||
|
||||
# ==================================================================
|
||||
# cif / celif / celse 编译期条件编译(软关键字,desugar 到 c.CIf 标记)
|
||||
# cif / celif / celse 编译期条件编译(软关键字,desugar 到 CIf 标记)
|
||||
# ==================================================================
|
||||
def _IsCIfStatementStart(self) -> bool:
|
||||
"""语句起始 NAME('cif') 是否按 cif 语句解析。
|
||||
@@ -1312,9 +1303,8 @@ class Parser(ExprParserMixin):
|
||||
return True
|
||||
|
||||
def _MakeCIfMarkerCall(self, attr: str, expr: N.expr, start: Token) -> N.Call:
|
||||
"""构造内部标记调用 `c.<attr>(expr)`(用户不可写;cif/defined 的 desugar)。"""
|
||||
func: N.Attribute = N.Attribute(
|
||||
value=N.Name(id='c', ctx=N.Load()), attr=attr, ctx=N.Load())
|
||||
"""构造内部标记调用 `<attr>(expr)`(用户不可写;cif/defined 的 desugar)。"""
|
||||
func: N.Name = N.Name(id=attr, ctx=N.Load())
|
||||
self._FixLoc(func, start)
|
||||
call: N.Call = N.Call(func=func, args=[expr], keywords=[])
|
||||
self._FixLoc(call, start)
|
||||
|
||||
+7
-10
@@ -1,6 +1,6 @@
|
||||
"""vast.unparser - AST 还原为源码字符串(与 ast.unparse 语义一致)
|
||||
|
||||
TPC 编译器多处用 ``ast.unparse`` 提取类型注解字符串(如 ``t.CArray[...]``、
|
||||
TPC 编译器多处用 ``ast.unparse`` 提取类型注解字符串(如 ``CArray[...]``、
|
||||
``list[i32, N]``、数组维度、默认值文本等)。本模块实现全部节点类型的
|
||||
源码还原,保证 ``import vast as ast`` 后这些调用零修改。
|
||||
"""
|
||||
@@ -88,22 +88,19 @@ class Unparser:
|
||||
ret: str = ''
|
||||
returns: N.expr | None = node.returns
|
||||
if is_extern and isinstance(returns, N.BinOp) and isinstance(returns.op, N.BitOr):
|
||||
# 还原 extern 原始注解:去掉改写时追加的 | t.State
|
||||
# 还原 extern 原始注解:去掉改写时追加的 | State
|
||||
right: N.expr = returns.right
|
||||
if (isinstance(right, N.Attribute) and right.attr == 'State'
|
||||
and isinstance(right.value, N.Name) and right.value.id == 't'):
|
||||
if isinstance(right, N.Name) and right.id == 'State':
|
||||
returns = returns.left
|
||||
if is_export and isinstance(returns, N.BinOp) and isinstance(returns.op, N.BitOr):
|
||||
# 还原 export 原始注解:去掉改写时追加的 | t.CExport
|
||||
# 还原 export 原始注解:去掉改写时追加的 | CExport
|
||||
right = returns.right
|
||||
if (isinstance(right, N.Attribute) and right.attr == 'CExport'
|
||||
and isinstance(right.value, N.Name) and right.value.id == 't'):
|
||||
if isinstance(right, N.Name) and right.id == 'CExport':
|
||||
returns = returns.left
|
||||
if is_define and isinstance(returns, N.BinOp) and isinstance(returns.op, N.BitOr):
|
||||
# 还原 define 原始注解:去掉改写时追加的 | t.CDefine
|
||||
# 还原 define 原始注解:去掉改写时追加的 | CDefine
|
||||
right = returns.right
|
||||
if (isinstance(right, N.Attribute) and right.attr == 'CDefine'
|
||||
and isinstance(right.value, N.Name) and right.value.id == 't'):
|
||||
if isinstance(right, N.Name) and right.id == 'CDefine':
|
||||
returns = returns.left
|
||||
if returns is not None:
|
||||
ret = f' -> {self._expr(returns)}'
|
||||
|
||||
Reference in new issue
Block a user