修复了跨模块 typedef 等问题

This commit is contained in:
TermiNexus committed 2026-08-02 03:29:41 +08:00
1 parent ebe3638ff5
commit a5d1841126
32 files changed
+38618 -39112

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
path = r'd:\Users\TermiNexus\Desktop\Viper_VSCode\packages\vipeye-internal\src\analyzer\types.ts'
with open(path, 'r', encoding='utf-8') as f:
text = f.read()
old1 = (
"// Viper \u6269\u5c55\uff1aViper C \u6d6e\u70b9\u7c7b\u578b\u540d\u79f0\u767d\u540d\u5355\u3002\n"
"const _viperCFloatTypeNames = new Set<string>([\n"
" 'CFloat', 'CDouble', 'CFloat8T', 'CFloat16T', 'CFloat32T', 'CFloat64T', 'CFloat128T',\n"
"]);\n"
)
new1 = old1 + (
"\n"
"// Viper \u6269\u5c55\uff1a\u5224\u65ad\u7c7b\u578b\u540d\u662f\u5426\u4e3a Viper C \u6d6e\u70b9\u7c7b\u578b\u3002\n"
"// \u7528\u4e8e\u534f\u8bae\u5339\u914d\u7b49\u573a\u666f\uff0c\u8ba9 CType \u6d6e\u70b9\u5b50\u7c7b\u6ee1\u8db3 SupportsFloat \u7b49\u6570\u503c\u534f\u8bae\u3002\n"
"export function isViperCFloatTypeName(name: string): boolean {\n"
" return _viperCFloatTypeNames.has(name);\n"
"}\n"
)
c1 = text.count(old1)
print('Edit1 match count:', c1)
assert c1 == 1, f'Edit1 match count: {c1}'
text = text.replace(old1, new1)
with open(path, 'w', encoding='utf-8') as f:
f.write(text)
print('isViperCFloatTypeName function added.')
@@ -21,6 +21,7 @@ import { DiagnosticLevel } from '../common/configOptions';
import { assert, assertNever, fail } from '../common/debug';
import { CreateTypeStubFileAction, Diagnostic } from '../common/diagnostic';
import { DiagnosticRule } from '../common/diagnosticRules';
import { IsViperDialect } from '../common/dialect';
import { stripFileExtension } from '../common/pathUtils';
import { convertTextRangeToRange } from '../common/positionUtils';
import { TextRange, getEmptyRange } from '../common/textRange';
@@ -426,6 +427,26 @@ export class Binder extends ParseTreeWalker {
return true;
}
// Viper 扩展:命名空间包(目录无 __init__.vp)标黄警告"疑似未完成"。
// Viper 是 AOT 静态语言,__init__.vp 缺失可能意味着模块未编写完整。
// 仅当导入的最终目标是目录(而非具体文件)时才标黄。
const lastResolvedUri = importResult.resolvedUris[importResult.resolvedUris.length - 1];
const isFinalTargetDirectory = !lastResolvedUri || lastResolvedUri.isEmpty();
if (
importResult.isImportFound &&
importResult.isNamespacePackage &&
isFinalTargetDirectory &&
IsViperDialect(this._fileInfo.executionEnvironment.dialect)
) {
this._fileInfo.diagnosticSink.addDiagnosticWithTextRange(
'warning',
LocMessage.viperNamespacePackageIncomplete().format({
importName: importResult.importName,
}),
node
);
}
// See if a source file was found but it's not part of a py.typed
// library and no type stub is found.
let reportStubMissing = false;
@@ -164,6 +164,7 @@ import {
isOverloaded,
isParamSpec,
isPossiblyUnbound,
isPureCModifierType,
isTypeSame,
isTypeVar,
isTypeVarTuple,
@@ -4789,7 +4790,14 @@ export class Checker extends ParseTreeWalker {
// The types of all return statement expressions were already checked
// against the declared type, but we need to verify the implicit None
// at the end of the function.
if (declaredReturnType && !functionNeverReturns && implicitlyReturnsNone) {
// Viper 扩展:返回类型包含 C 声明标记(t.State 等,等价 CExport | CExtern)
// 视为声明性函数(C extern 声明,如 w32 API 的 BOOL | t.State: pass),不要求返回值。
const isPureModifierReturn =
IsViperDialect(this._fileInfo.executionEnvironment.dialect) &&
declaredReturnType !== undefined &&
isPureCModifierType(declaredReturnType);
if (declaredReturnType && !functionNeverReturns && implicitlyReturnsNone && !isPureModifierReturn) {
if (isNever(declaredReturnType)) {
// If the function consists entirely of "...", assume that it's
// an abstract method or a protocol method and don't require that
@@ -4980,9 +4988,15 @@ export class Checker extends ParseTreeWalker {
}
// Enum members should not have type annotations.
// Viper 扩展:CEnum 子类允许类型注解成员(如 FR_OK: t.State = 0),
// 跳过此错误报告。
const typedDecls = symbol.getTypedDeclarations();
if (typedDecls.length > 0) {
if (typedDecls[0].type === DeclarationType.Variable && typedDecls[0].inferredTypeSource) {
if (
!IsViperDialect(this._fileInfo.executionEnvironment.dialect) &&
typedDecls[0].type === DeclarationType.Variable &&
typedDecls[0].inferredTypeSource
) {
this._evaluator.addDiagnostic(
DiagnosticRule.reportGeneralTypeIssues,
LocMessage.enumMemberTypeAnnotation(),
@@ -5009,7 +5023,8 @@ export class Checker extends ParseTreeWalker {
}
// Look for an enum attribute annotated with "Final".
if (decls[0].isFinal) {
// Viper 扩展:CEnum 子类允许类型注解成员,跳过 Final 注解错误。
if (decls[0].isFinal && !IsViperDialect(this._fileInfo.executionEnvironment.dialect)) {
this._evaluator.addDiagnostic(
DiagnosticRule.reportGeneralTypeIssues,
LocMessage.enumMemberTypeAnnotation(),
+16 -1
View File
@@ -8,6 +8,7 @@
*/
import { assert } from '../common/debug';
import { IsViperDialect } from '../common/dialect';
import { PythonVersion, pythonVersion3_13 } from '../common/pythonVersion';
import { ArgCategory, ExpressionNode, NameNode, ParseNode, ParseNodeType } from '../parser/parseNodes';
import { getFileInfo } from './analyzerNodeInfo';
@@ -380,10 +381,24 @@ export function transformTypeForEnumMember(
nameNode.parent?.nodeType === ParseNodeType.TypeAnnotation &&
nameNode.parent.d.valueExpr === nameNode
) {
if (ignoreAnnotation) {
// Viper 扩展:CEnum 子类的类型注解成员始终视为枚举成员。
// Python 的 Enum 要求成员有赋值(如 RED = 1),但 Viper 的 CEnum
// 允许只用类型注解声明成员(如 RES_PARERR: State)。
// 在 Viper 方言下,无论 ignoreAnnotation 如何,都设置 isMemberOfEnumeration = true。
if (ignoreAnnotation || IsViperDialect(getFileInfo(nameNode).executionEnvironment.dialect)) {
isMemberOfEnumeration = true;
}
declaredTypeNode = nameNode.parent.d.annotation;
// Viper 扩展:处理"类型注解 + 赋值"组合(如 FR_OK: t.State = 0)。
// 当 TypeAnnotation 的 parent 是 Assignment 时,提取赋值右侧表达式,
// 使 assignedType 能正确评估(如 0 → int)。declaredType(t.State)仍优先。
if (
nameNode.parent.parent?.nodeType === ParseNodeType.Assignment &&
nameNode.parent.parent.d.leftExpr === nameNode.parent
) {
valueTypeExprNode = nameNode.parent.parent.d.rightExpr;
}
}
// The spec specifically excludes names that start and end with a single underscore.
@@ -357,9 +357,19 @@ export class ImportResolver {
getImportRoots(execEnv: ExecutionEnvironment, forLogging = false) {
const roots = [];
// Viper 模式优先搜索 vipershed-fallback/stdlib(Viper 特有模块:t/c/stdio 等),
// 再搜索 typeshed-fallback/stdlib(Python 通用模块:builtins/typing 等)。
// typeshed root 已改为 typeshed-fallback,确保 builtins 可被隐式加载。
// Viper 模式:项目 includes(.vpj 中配置的真实 .vp 源文件路径)必须最优先,
// 让 LSP 直接解析真实源码生成注解,而非依赖预写的 .vpi 存根。
// The "default" workspace has a root-less execution environment; ignore it.
if (IsViperDialect(this._configOptions.dialect)) {
if (execEnv.root) {
roots.push(execEnv.root);
}
appendArray(roots, execEnv.extraPaths);
}
// vipershed-fallback/stdlib 作为回退:仅提供 t.vpi/c.vpi 等无真实 .vp 源码
// 的核心模块存根(t.py/c.py 是编译器实现,依赖内部模块无法被 LSP 解析)。
// 排在项目 includes 之后,确保有真实 .vp 的模块优先用源码。
if (IsViperDialect(this._configOptions.dialect)) {
const vipershed = PythonPathUtils.getVipershedFallbackPath(this.fileSystem);
if (vipershed && !vipershed.isEmpty()) {
@@ -370,6 +380,8 @@ export class ImportResolver {
}
}
// typeshed-fallback/stdlib 提供 Python 通用模块(builtins/typing 等)。
// typeshed root 已改为 typeshed-fallback,确保 builtins 可被隐式加载。
const stdTypeshed = this._getStdlibTypeshedPath(
this._configOptions.typeshedPath,
execEnv.pythonVersion,
@@ -379,13 +391,14 @@ export class ImportResolver {
roots.push(stdTypeshed);
}
// The "default" workspace has a root-less execution environment; ignore it.
if (execEnv.root) {
roots.push(execEnv.root);
// 非 Viper 模式:保持原有顺序(root 与 extraPaths 在 typeshed 之后)。
if (!IsViperDialect(this._configOptions.dialect)) {
if (execEnv.root) {
roots.push(execEnv.root);
}
appendArray(roots, execEnv.extraPaths);
}
appendArray(roots, execEnv.extraPaths);
if (this._configOptions.stubPath) {
roots.push(this._configOptions.stubPath);
}
@@ -1546,19 +1559,14 @@ export class ImportResolver {
continue;
}
if (IsViperDialect(execEnv.dialect)) {
// Viper 模式:最后一部分目录存在但未找到模块文件
// (__init__.vp 或 同名.vp),不退化为 namespace package,
// 直接中断解析使 isImportFound=false,让 binder 在 import
// 语句处报 reportMissingImports 错误。
// Viper 是 AOT 静态语言,最终模块必须有实际源文件。
importLogger?.log(`Viper import failed: directory '${dirPath}' has no module file`);
} else {
importLogger?.log(`Partially resolved import with directory '${dirPath}'`);
resolvedPaths.push(Uri.empty());
implicitImports = this.findImplicitImports(importName, dirPath, [pyFilePath, pyiFilePath]);
isNamespacePackage = true;
}
// 最后一部分目录存在但未找到模块文件(__init__ 或同名 .vp),
// 退化为 namespace package,使 isImportFound=true。
// Viper 与 Python 均允许此行为:便于在编写时提示文件夹内的 .vp/.py 库。
// findImplicitImports 会扫描目录内的 .vp/.vpi/.py/.pyi 文件作为隐式导入。
importLogger?.log(`Partially resolved import with directory '${dirPath}'`);
resolvedPaths.push(Uri.empty());
implicitImports = this.findImplicitImports(importName, dirPath, [pyFilePath, pyiFilePath]);
isNamespacePackage = true;
}
if (!pyTypedInfo && lookForPyTyped) {
File diff suppressed because it is too large. Load diff
@@ -844,6 +844,89 @@ export function getEvaluationNodeForAssignmentExpression(
return undefined;
}
// Determines whether `node` sits within the annotation sub-tree of a class
// member type annotation (e.g. the `t.CInt` part of `id: t.CInt`, including
// nested sub-expressions such as `sheet` in `sheet: sheet.Sheet | t.CPtr`).
//
// Per PEP 526, such annotations are evaluated in the class's enclosing scope,
// not the class scope itself, so a member name never shadows a module-level
// import while the annotation is being resolved. The member name node itself
// (`valueExpr`) and any nodes inside a nested method body are excluded.
function isInClassMemberTypeAnnotation(node: ParseNode): boolean {
let curNode: ParseNode | undefined = node;
while (curNode) {
const parent = curNode.parent;
if (
parent?.nodeType === ParseNodeType.TypeAnnotation &&
parent.d.annotation === curNode
) {
// curNode is the annotation expression (or a descendant reached via
// the loop below). Verify the TypeAnnotation lives directly in a
// class suite (not inside a nested function).
let ancestor: ParseNode | undefined = parent.parent;
while (ancestor) {
if (ancestor.nodeType === ParseNodeType.Function) {
return false;
}
if (ancestor.nodeType === ParseNodeType.Class) {
return true;
}
ancestor = ancestor.parent;
}
return false;
}
curNode = parent;
}
return false;
}
// Per PEP 526 and Viper's scoping rules, annotations on a method's signature
// (parameter annotations and the return annotation) are evaluated in the
// class's enclosing scope, not the class scope. This mirrors the treatment of
// class member variable annotations: a module-level import whose name matches
// a class member must not be shadowed by that member while resolving the
// method signature. Annotations inside the method *body* (e.g. local variable
// annotations) are unaffected because they use the function scope, which
// already skips the class scope during name lookup.
function isInClassMethodSignatureAnnotation(node: ParseNode): boolean {
let curNode: ParseNode | undefined = node;
let funcNode: ParseNode | undefined;
// Walk up to find whether the node lives within a parameter annotation or
// a function return annotation.
while (curNode) {
const parent = curNode.parent;
if (parent?.nodeType === ParseNodeType.Parameter && parent.d.annotation === curNode) {
// Parameter annotation: the enclosing function is the parameter's parent.
funcNode = parent.parent ?? undefined;
break;
}
if (parent?.nodeType === ParseNodeType.Function && parent.d.returnAnnotation === curNode) {
funcNode = parent;
break;
}
curNode = parent;
}
if (!funcNode || funcNode.nodeType !== ParseNodeType.Function) {
return false;
}
// The function must be a direct member of a class (not a nested function
// inside a method body, and not a module-level function).
let ancestor: ParseNode | undefined = funcNode.parent;
while (ancestor) {
if (ancestor.nodeType === ParseNodeType.Function) {
return false;
}
if (ancestor.nodeType === ParseNodeType.Class) {
return true;
}
ancestor = ancestor.parent;
}
return false;
}
// Returns the parse node corresponding to the scope that is used to evaluate
// a symbol referenced in the specified node.
export function getEvaluationScopeNode(node: ParseNode): EvaluationScopeInfo {
@@ -945,8 +1028,31 @@ export function getEvaluationScopeNode(node: ParseNode): EvaluationScopeInfo {
}
if (prevNode === curNode.d.suite) {
// PEP 526: class member type annotations (e.g. the `t.CInt`
// in `id: t.CInt`, or `sheet.Sheet | t.CPtr` in
// `sheet: sheet.Sheet | t.CPtr`) are evaluated in the
// class's enclosing scope, not the class scope. Otherwise a
// module-level import whose name matches a member being
// declared would be shadowed by that member, breaking the
// annotation. Only the annotation sub-tree is affected;
// the member name itself and all other class-body nodes
// continue to use the class scope.
if (isInClassMemberTypeAnnotation(node) || isInClassMethodSignatureAnnotation(node)) {
if (curNode.d.typeParams) {
const scopeNode = curNode.d.typeParams;
if (getScope(scopeNode) !== undefined) {
return {
node: scopeNode,
useChainedModuleLevelScopes: true,
};
}
}
break;
}
// All other nodes within the class suite use the class scope.
if (getScope(curNode) !== undefined) {
return { node: curNode };
return { node: curNode, useChainedModuleLevelScopes: true };
}
}
@@ -67,6 +67,7 @@ import {
findConfigFileHereOrUp,
findPyprojectTomlFile,
findPyprojectTomlFileHereOrUp,
findVpjInChildDirs,
} from './serviceUtils';
import { SourceEnumerator } from './sourceEnumerator';
import { IPythonMode } from './sourceFile';
@@ -831,6 +832,14 @@ export class AnalyzerService {
// project root directory contains the config file.
configFilePath = findConfigFile(this.fs, projectRoot);
// Viper 扩展:LSP 模式下,如果工作区根没有配置文件,扫描一级子目录查找 .vpj。
// 支持工作区根(如 Viper_VSCode)包含子项目(如 Test/project.vpj)的场景。
// 找到 .vpj 后,projectRoot 调整为 .vpj 所在目录(后续 L842 逻辑),
// .vpj 的 includes 会被 _initializeFromViperProjectJson 解析为 defaultExtraPaths。
if (!configFilePath && commandLineOptions.fromLanguageServer) {
configFilePath = findVpjInChildDirs(this.fs, projectRoot);
}
// If viper is being executed from the command line, the working
// directory may be deep within a project, and we need to walk up the
// directory hierarchy to find the project root.
@@ -69,6 +69,32 @@ export function findVpjFileInDir(fs: ReadOnlyFileSystem, dirUri: Uri): Uri | und
return undefined;
}
// Viper 扩展:在目录的一级子目录中查找 .vpj 文件。
// 用于 LSP 模式下工作区根(如 Viper_VSCode)未直接包含 .vpj,
// 但子目录(如 Test/)包含 Viper 项目配置的场景。
// 仅扫描一级子目录(非递归),避免深层遍历开销。
// 失败时返回 undefined。
export function findVpjInChildDirs(fs: ReadOnlyFileSystem, dirUri: Uri): Uri | undefined {
try {
if (!fs.existsSync(dirUri)) {
return undefined;
}
const entries = fs.readdirEntriesSync(dirUri);
for (const entry of entries) {
if (entry.isDirectory()) {
const childDir = dirUri.resolvePaths(entry.name);
const vpjFile = findVpjFileInDir(fs, childDir);
if (vpjFile) {
return vpjFile;
}
}
}
} catch {
// 读取目录失败:跳过
}
return undefined;
}
// 校验 project.json / project.vpj 是否为 Viper(TransPyC)项目配置。
// project.json 是常见文件名,仅当含 source_dir / compiler / linker 之一时才视为 Viper 配置。
// 读取或解析失败时按非 Viper 项目处理,返回 false。
File diff suppressed because it is too large. Load diff
@@ -99,6 +99,9 @@ export const enum PrintTypeFlags {
// Omit TypeVar scopes.
OmitTypeVarScope = 1 << 13,
// Viper 方言:将 NoneType 显示为 CVoid(C 语义 void)。
ViperDialect = 1 << 14,
}
export type FunctionReturnTypeCallback = (type: FunctionType) => Type;
@@ -736,7 +739,8 @@ function printUnionType(
if (noneIndex >= 0 && !subtypeHandledSet.has(noneIndex)) {
const typeWithoutNone = removeNoneFromUnion(type);
if (isNever(typeWithoutNone)) {
return 'None';
// Viper 方言下 None 表示 CVoid(C 语义 void)。
return (printTypeFlags & PrintTypeFlags.ViperDialect) !== 0 ? 'CVoid' : 'None';
}
const optionalType = printTypeInternal(
@@ -1596,5 +1600,10 @@ export function getPrintTypeFlags(configOptions: ConfigOptions): PrintTypeFlags
flags |= PrintTypeFlags.PEP604;
}
// Viper 方言下 NoneType 显示为 CVoid。
if (configOptions.dialect === 'viper') {
flags |= PrintTypeFlags.ViperDialect;
}
return flags;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -594,6 +594,22 @@ export namespace Localizer {
new ParameterizedString<{ importName: string; venv: string }>(
getRawString('Diagnostic.importSourceResolveFailure')
);
export const viperNamespacePackageIncomplete = () =>
new ParameterizedString<{ importName: string }>(
getRawString('Diagnostic.viperNamespacePackageIncomplete')
);
export const viperUnresolvedImportName = () =>
new ParameterizedString<{ name: string }>(
getRawString('Diagnostic.viperUnresolvedImportName')
);
export const viperUnknownMemberAccess = () =>
new ParameterizedString<{ memberName: string }>(
getRawString('Diagnostic.viperUnknownMemberAccess')
);
export const viperGlobalAssignmentWithoutGlobal = () =>
new ParameterizedString<{ name: string }>(
getRawString('Diagnostic.viperGlobalAssignmentWithoutGlobal')
);
export const importSymbolUnknown = () =>
new ParameterizedString<{ name: string }>(getRawString('Diagnostic.importSymbolUnknown'));
export const incompatibleMethodOverride = () =>
@@ -641,6 +641,10 @@
"importDepthExceeded": "Import chain depth exceeded {depth}",
"importResolveFailure": "Import \"{importName}\" could not be resolved",
"importSourceResolveFailure": "Import \"{importName}\" could not be resolved from source",
"viperNamespacePackageIncomplete": "Namespace package \"{importName}\" is missing __init__.vp, possibly incomplete",
"viperUnresolvedImportName": "Unresolved import name \"{name}\"",
"viperUnknownMemberAccess": "Cannot access member \"{memberName}\" on unresolved type, object may be undefined",
"viperGlobalAssignmentWithoutGlobal": "Global variable \"{name}\" requires global declaration when writing inside a function",
"importSymbolUnknown": "\"{name}\" is unknown import symbol",
"incompatibleMethodOverride": "Method \"{name}\" overrides class \"{className}\" in an incompatible manner",
"inconsistentIndent": "Unindent amount does not match previous indent",
@@ -265,6 +265,10 @@
"importDepthExceeded": "导入链深度超过 {depth}",
"importResolveFailure": "无法解析导入“{importName}”",
"importSourceResolveFailure": "无法从源解析导入“{importName}”",
"viperNamespacePackageIncomplete": "命名空间包“{importName}”缺少 __init__.vp,疑似未完成",
"viperUnresolvedImportName": "无法解析的导入名称“{name}”",
"viperUnknownMemberAccess": "无法解析类型上的成员“{memberName}”访问,对象可能未定义",
"viperGlobalAssignmentWithoutGlobal": "全局变量“{name}”在函数内写入需要 global 声明",
"importSymbolUnknown": "“{name}”是未知的导入符号",
"incompatibleMethodOverride": "方法“{name}”以不兼容的方式替代类“{className}”",
"inconsistentIndent": "取消缩进量与以前的缩进不匹配",
@@ -1 +1,4 @@
# _typeshed 占位。
# 定义 NoneType 供类型求值器使用(getNoneType() 通过 _typeshed.NoneType 查找)。
# 直接定义而非从 types 导入,避免 _typeshed ↔ types 循环导入。
class NoneType: ...
@@ -1,206 +0,0 @@
# Viper 命令行参数解析库 argparse 存根。
# Python argparse 风格的 C 实现,依赖 memhub 和 hashtable。
# 姑息策略:
# - 类型/动作常量映射为 int
# - _mbuddy 为模块级全局 MemBuddy 指针(int)
# - Argument/ParsedArgs/ArgumentParser 内部指针字段映射为 int
import t
import string
import stdio
import memhub
import hashtable
# ============================================================
# 类型常量
# ============================================================
STRING: int = 0 # 字符串类型
INT: int = 1 # 整数类型
BOOL: int = 2 # 布尔类型
# 动作常量
STORE: int = 0 # 存储值(默认)
STORE_TRUE: int = 1 # 出现时存 True
STORE_FALSE: int = 2 # 出现时存 False
COUNT: int = 3 # 计数出现次数
# 限制
MAX_ARGS: int = 32 # 单个 parser 最大参数数
# 模块级 mbuddy 指针(由用户在 main 中赋值)
_mbuddy: int # memhub.MemBuddy | t.CPtr
# ============================================================
# Argument - 参数定义结构体
# ============================================================
class Argument:
"""命令行参数定义。"""
name: str # "--input" 或 "output"(位置参数)
short_name: str # "-i" 或 None
help_text: str # 帮助文本
arg_type: int # STRING, INT, BOOL
action: int # STORE, STORE_TRUE, STORE_FALSE, COUNT
default_int: int # INT 类型默认值
default_str: str # STRING 类型默认值
required: bool # 是否必须
is_positional: bool # 是否位置参数
dest: str # 查找键名("--input" → "input")
# ============================================================
# ParsedArgs - 解析结果
# ============================================================
class ParsedArgs:
"""参数解析结果,内部用 HashTable 存储。"""
_ht: int # hashtable.HashTable 指针
__mbuddy__: int # memhub.MemBuddy 指针
def __new__(self, mb: int) -> int:
"""堆分配 ParsedArgs 对象。"""
return 0
def __init__(self, mb: int) -> None:
"""初始化解析结果。
Args:
mb: MemBuddy 指针(int)
"""
...
def get_str(self, name: str) -> str:
"""获取字符串值。
Args:
name: 键名(dest)
Returns:
字符串值,键不存在返回 None
"""
return ""
def get_int(self, name: str) -> int:
"""获取整数值。
Args:
name: 键名(dest)
Returns:
整数值,键不存在返回 0
"""
return 0
def get_bool(self, name: str) -> int:
"""获取布尔值(返回 1 或 0)。
Args:
name: 键名(dest)
Returns:
1 或 0,键不存在返回 0
"""
return 0
def has(self, name: str) -> bool:
"""检查键是否存在。"""
return False
def _set_str(self, name: str, val: str) -> None: ...
def _set_int(self, name: str, val: int) -> None: ...
def _set_bool(self, name: str, val: bool) -> None: ...
# ============================================================
# ArgumentParser - 命令行参数解析器
# ============================================================
class ArgumentParser:
"""命令行参数解析器。
用法:
argparse._mbuddy = mb
parser = ArgumentParser("myprog", "A test", pool=mb)
parser.add_argument("--input", "-i", arg_type=argparse.STRING,
required=True, help="input file")
parser.add_argument("--count", "-c", arg_type=argparse.INT,
default=0, help="repeat count")
parser.add_argument("--verbose", "-v", action=argparse.STORE_TRUE,
help="verbose mode")
parser.add_argument("output", arg_type=argparse.STRING,
help="output path")
args = parser.parse_args(argc, argv)
if args is not None:
inp: str = args.get_str("input")
cnt: int = args.get_int("count")
verb: int = args.get_bool("verbose")
out: str = args.get_str("output")
argparse.release(args)
"""
_prog: str
_description: str
_args: int # Argument 数组基址(指针)
_arg_count: int
__mbuddy__: int # memhub.MemBuddy 指针
def __new__(self, prog: str = "", description: str = "",
pool: int = 0) -> int:
"""堆分配 ArgumentParser 对象。"""
return 0
def __init__(self, prog: str = "", description: str = "",
pool: int = 0) -> None:
"""初始化解析器。
Args:
prog: 程序名
description: 描述文本
pool: MemBuddy 指针(int),为 0 时使用模块级 _mbuddy
"""
...
def add_argument(self, name: str = "", short: str = "",
arg_type: int = 0, default: int = 0,
default_str: str = "", required: bool = False,
action: int = 0, help: str = "") -> None:
"""注册一个命令行参数。
Args:
name: 参数名("--input" 或 "output")
short: 短选项("-i"),可选
arg_type: 类型(STRING/INT/BOOL)
default: INT 默认值
default_str: STRING 默认值
required: 是否必须
action: 动作(STORE/STORE_TRUE/STORE_FALSE/COUNT)
help: 帮助文本
"""
...
def parse_args(self, argc: int, argv: int) -> int:
"""解析命令行参数。
Args:
argc: 参数个数
argv: 参数数组(char**,指针,int),argv[0] 为程序名
Returns:
ParsedArgs 指针(int),失败返回 0(None)
"""
return 0
def print_help(self) -> None:
"""打印帮助信息到 stdout。"""
...
def print_usage(self) -> None:
"""打印用法简述到 stdout。"""
...
# ============================================================
# release - 释放 ParsedArgs 及其内部资源
# ============================================================
def release(args: int) -> None:
"""释放 ParsedArgs 对象及其内部 HashTable。
Args:
args: ParsedArgs 指针(int),为 0(None)无操作
"""
...
@@ -2,13 +2,14 @@
# 所有函数返回值类型姑息映射为 Python 类型。
from typing import Any, TypeVar
import t
T = TypeVar('T')
def Addr(x: T) -> int:
"""取地址 &x,返回指针(int)。"""
return 0
def Addr(x: T) -> t.CPtr[T]:
"""取地址 &x,返回指向 T 的指针(&x)。"""
...
def Deref(ptr: int) -> T:
"""解引用 *ptr。"""
@@ -1,140 +0,0 @@
# Viper 开放寻址哈希表库 hashtable 存根。
# 使用线性探测处理冲突,支持自动扩容和墓碑删除。
# 键类型固定为 str (i8*),值类型为 void* (通用指针)。
# 姑息策略:
# - __slots__ 等指针字段映射为 int(指针整数)
# - __mbuddy__ 为 MemBuddy 指针(int)
# - 值指针映射为 int
# - 键存在性/删除返回 int(0/1)
import t
import string
import memhub
# 槽大小: hash(8) + key(8) + value(8) = 24 字节
_HT_SLOT_SIZE: int = 24
# FNV-1a 64-bit 常量
_FNV_OFFSET: int = 0xcbf29ce484222325
_FNV_PRIME: int = 0x100000001b3
def _fnv1a_hash(key: str) -> int:
"""FNV-1a 64-bit 哈希函数。
保证返回值 >= 2(避开空槽 0 和墓碑 1)。
"""
return 0
class HashTable:
"""开放寻址哈希表,使用线性探测处理冲突。
键类型固定为 str (i8*),值类型为 void* (通用指针)。
使用 mbuddy 分配器管理内存。负载因子超过 0.75 时自动扩容。
用法:
mb: memhub.MemBuddy = memhub.MemBuddy(arena, arena_size)
ht: HashTable = HashTable(mb)
ht.set_int("x", 42)
p: int = ht["x"]
v: int = c.Deref(p)
"""
__slots__: int # 槽位数组基址(指针)
__count__: int # 已用条目数
__capacity__: int # 槽位总数(2 的幂)
__tombstones__: int # 墓碑数
__mbuddy__: int # memhub.MemBuddy 指针
__iter_index__: int # 迭代游标
def __new__(self, mb: int) -> int:
"""堆分配 HashTable 对象。
Args:
mb: MemBuddy 指针(int)
Returns:
对象指针(int)
"""
return 0
def __init__(self, mb: int) -> None:
"""初始化哈希表。
Args:
mb: MemBuddy 指针(int)
"""
...
def __setitem__(self, key: str, val: int) -> None:
"""插入或更新键值对。
Args:
key: 键字符串
val: 值指针(int),自动取地址
"""
...
def __getitem__(self, key: str) -> int:
"""查找 key,返回值指针。
Returns:
值指针(int),不存在返回 0(None)
"""
return 0
def __contains__(self, key: str) -> int:
"""检查 key 是否存在。
Returns:
存在返回 1,不存在返回 0
"""
return 0
def __delitem__(self, key: str) -> int:
"""删除 key。
Returns:
成功返回 1,key 不存在返回 0
"""
return 0
def __len__(self) -> int:
"""返回已用条目数。"""
return 0
def __iter__(self) -> 'HashTable':
"""初始化迭代器,返回 self。"""
return self
def __next__(self) -> str:
"""返回下一个键。迭代结束抛出 StopIteration。"""
raise StopIteration
def get(self, key: str, default: int) -> int:
"""返回值指针,不存在则返回 default。
Args:
key: 键字符串
default: 默认值指针(int)
Returns:
值指针(int)
"""
return 0
def set_int(self, key: str, val: int) -> None:
"""存储 int 值。值复制到 mbuddy 持久存储。
Args:
key: 键字符串
val: 整数值
"""
...
def set_str(self, key: str, val: str) -> None:
"""存储 str 值。直接存储字符串指针。
Args:
key: 键字符串
val: 值字符串
"""
...
@@ -1,210 +0,0 @@
# Viper 链表数据结构库 linkedlist 存根。
# 提供 LinkedNode/SListNode/GSListNode/GSList/GTreeNode 等节点类型。
# 姑息策略:
# - 节点指针字段映射为节点类型本身(含 None 表示空指针)
# - 计数字段映射为 int
# - 返回节点指针映射为节点类型或 None
from typing import Generic, TypeVar, Optional
T = TypeVar('T')
# ============================================================
# LinkedNode: 非多态继承基类(@t.NoVTable)
# 子类继承此类即"启用"标准链表/树形结构能力:
# - 双向兄弟链表(next/prev)→ O(1) 删除
# - 父子树结构(child/last_child/parent)→ O(1) 追加子节点
# - 子节点计数(child_count)
# ============================================================
class LinkedNode:
"""双向兄弟链表 + 父子树节点基类。
字段展平嵌入子类,无 vtable 开销(对应 C++ 非多态继承)。
用法:
class MyNode(LinkedNode):
value: int
root: MyNode = MyNode()
child: MyNode = MyNode()
root.append(child)
child.detach()
"""
next: Optional['LinkedNode'] # 下一个兄弟节点
prev: Optional['LinkedNode'] # 上一个兄弟节点(双向链表,O(1) 删除)
child: Optional['LinkedNode'] # 第一个子节点
last_child: Optional['LinkedNode'] # 最后一个子节点(O(1) 追加)
parent: Optional['LinkedNode'] # 父节点
child_count: int # 子节点数
def append(self, node: 'LinkedNode') -> None:
"""将 node 追加为 self 的最后一个子节点(O(1))。
若 node 已在某链表中,调用方应先 node.detach() 再 append。
"""
...
def prepend(self, node: 'LinkedNode') -> None:
"""将 node 插入为 self 的第一个子节点(O(1))。"""
...
def insert_before(self, node: 'LinkedNode', new_node: 'LinkedNode') -> None:
"""在 node 之前插入 new_node(node 必须是 self 的子节点,O(1))。"""
...
def insert_after(self, node: 'LinkedNode', new_node: 'LinkedNode') -> None:
"""在 node 之后插入 new_node(node 必须是 self 的子节点,O(1))。"""
...
def remove_child(self, node: 'LinkedNode') -> None:
"""从 self 的子链表中摘除 node(O(1))。node 必须是 self 的直接子节点。"""
...
def detach(self) -> None:
"""将 self 从其所在兄弟链表中摘除(O(1))。
调用后 self 的 next/prev/parent 被清空,child 链不受影响。
"""
...
def unlink(self) -> None:
"""断开 self 的所有连接(兄弟 + 父子),不递归处理子节点。"""
...
def has_children(self) -> int:
"""返回 1 若有子节点,否则 0。"""
return 0
def child_at(self, index: int) -> Optional['LinkedNode']:
"""返回第 index 个子节点(O(n),从 0 开始),越界返回 None。"""
return None
def count_children(self) -> int:
"""遍历计算子节点数(O(n)),用于校验 child_count。"""
return 0
def first_sibling(self) -> Optional['LinkedNode']:
"""返回兄弟链表的头节点(沿 prev 回溯)。"""
return None
def last_sibling(self) -> Optional['LinkedNode']:
"""返回兄弟链表的尾节点(沿 next 前进)。"""
return None
# ============================================================
# SListNode: 单向链表节点(@t.NoVTable)
# 轻量级单向链表,仅 Next 指针,无 prev/parent/child
# ============================================================
class SListNode:
"""单向链表节点。"""
Next: Optional['SListNode'] # 下一个节点
def append(self, node: 'SListNode') -> 'SListNode':
"""将 node 追加到链表末尾(O(n)),返回 self(head)。"""
return self
def append_after(self, node: 'SListNode') -> 'SListNode':
"""将 node 追加到 self 之后(O(1)),返回新的 tail(即 node)。"""
return node
def count(self) -> int:
"""遍历计算链表长度(O(n))。"""
return 0
def at(self, index: int) -> Optional['SListNode']:
"""返回第 index 个节点(O(n),从 0 开始),越界返回 None。"""
return None
def remove(self, node: 'SListNode') -> 'SListNode':
"""从链表中移除 node(O(n)),返回新的 head(self)。"""
return self
# ============================================================
# GSListNode[T]: 泛型单向链表节点(@t.NoVTable + PEP 695 泛型)
# 递归泛型用法:class GNode(GSListNode[GNode]):
# ============================================================
class GSListNode(Generic[T]):
"""泛型单向链表节点。
相比 SListNode,Next 字段类型为 T,特化后无需向下转型。
"""
Next: Optional[T]
# ============================================================
# GSList[T]: 泛型单向链表容器(@t.NoVTable + PEP 695 泛型)
# 持有 Head/Tail/Count,提供 O(1) append 和 O(n) at
# ============================================================
class GSList(Generic[T]):
"""泛型单向链表容器。
节点类型 T 必须继承 GSListNode[T](以获得 Next 字段)。
用法:
lst: GSList[GNode] = GSList[GNode]()
lst.append(node)
"""
Head: Optional[T]
Tail: Optional[T]
Count: int
def __init__(self) -> None:
"""初始化空链表。"""
...
def append(self, node: T) -> None:
"""将 node 追加到链表末尾(O(1))。"""
...
def count(self) -> int:
"""返回节点数(O(1))。"""
return 0
def at(self, index: int) -> Optional[T]:
"""返回第 index 个节点(O(n),从 0 开始),越界返回 None。"""
return None
# ============================================================
# GTreeNode[T]: 泛型树节点(@t.NoVTable + PEP 695 泛型)
# 强类型版本的 LinkedNode,所有指针字段类型为 T
# 递归泛型用法:class AST(GTreeNode[AST]):
# ============================================================
class GTreeNode(Generic[T]):
"""泛型树节点。
强类型版本的 LinkedNode,提供:
- 双向兄弟链表(Next/Prev)→ O(1) 删除
- 父子树结构(Child/LastChild/Parent)→ O(1) 追加子节点
- 子节点计数(Count)
"""
Next: Optional[T] # 下一个兄弟节点
Prev: Optional[T] # 上一个兄弟节点(双向链表,O(1) 删除)
Child: Optional[T] # 第一个子节点
LastChild: Optional[T] # 最后一个子节点(O(1) 追加)
Parent: Optional[T] # 父节点
Count: int # 子节点数
def append(self, node: T) -> None:
"""将 node 追加为 self 的最后一个子节点(O(1))。"""
...
def prepend(self, node: T) -> None:
"""将 node 插入为 self 的第一个子节点(O(1))。"""
...
def detach(self) -> None:
"""将 self 从其所在兄弟链表中摘除(O(1))。"""
...
def has_children(self) -> int:
"""返回 1 若有子节点,否则 0。"""
return 0
def child_at(self, index: int) -> Optional[T]:
"""返回第 index 个子节点(O(n),从 0 开始),越界返回 None。"""
return None
def count_children(self) -> int:
"""遍历计算子节点数(O(n)),用于校验 Count。"""
return 0
@@ -1,243 +0,0 @@
# Viper 统一内存管理库 memhub 存根。
# 提供 MemManager 多态基类及 MemPool/MemSlab/MemBuddy 三个子类。
# 姑息策略:
# - 指针字段映射为 int(指针整数)
# - 大小/计数映射为 int
# - 返回指针映射为 int(NULL=0 表示失败)
import t
import string
import stdio
# ============================================================
# 常量
# ============================================================
MEMHUB_ALIGN: int = 8 # 对齐粒度
MEMSLAB_MIN_BLOCK: int = 16 # MemSlab 最小块大小
MEMSLAB_BITMAP_BYTES: int = 256 # MemSlab 位图字节数
MEMBUDDY_MIN_BLOCK: int = 32 # MemBuddy 最小块大小
MEMBUDDY_MAX_ORDERS: int = 32 # MemBuddy 最大阶数
MEMBUDDY_HEADER_SIZE: int = 8 # MemBuddy 块头大小
def _align_up(val: int, align: int) -> int:
"""向上对齐到 align 的倍数。"""
return 0
def _largest_pow2_le(val: int) -> int:
"""返回不超过 val 的最大 2 的幂。"""
return 0
def _block_size_at_order(order: int) -> int:
"""返回指定阶数的块大小。"""
return 0
# ============================================================
# MemManager - 多态基类(@t.CVTable)
# 子类通过 vtable 覆盖 alloc/free/reset,支持多态调用
# ============================================================
class MemManager:
"""内存管理器多态基类。
子类:
MemPool - arena bump 分配器(不支持单个 free)
MemSlab - 定长块池(位图跟踪)
MemBuddy - 伙伴系统(支持合并)
"""
__provides__: list # ['__memmgr__']
base: int # 内存区起始地址(指针)
size: int # 内存区总大小
def __init__(self, base: int, size: int) -> None:
"""初始化内存管理器。
Args:
base: 内存区起始地址(指针,int)
size: 内存区总大小(字节)
"""
...
# === 虚函数(子类覆盖) ===
def alloc(self, size: int) -> int:
"""分配 size 字节内存。
Returns:
成功返回指针(int),失败返回 0(NULL)
"""
return 0
def free(self, ptr: int) -> int:
"""释放内存。
Returns:
成功返回 1,失败返回 0
"""
return 0
def reset(self) -> int:
"""重置内存区(回收全部)。
Returns:
成功返回 1
"""
return 0
# === 具体方法(自动多态分派) ===
def calloc(self, count: int, size: int) -> int:
"""分配 count*size 字节并清零。"""
return 0
def realloc(self, ptr: int, new_size: int) -> int:
"""重新调整分配大小。"""
return 0
def __enter__(self) -> 'MemManager':
"""进入 with 上下文,返回 self。"""
...
def __exit__(self) -> None:
"""退出 with 上下文,调用 reset。"""
...
def alloc_buf(self, capacity: int) -> int:
"""分配一个 viperio.Buf 及其数据区。
Args:
capacity: 数据区容量
Returns:
Buf 指针(int),失败返回 0
"""
return 0
# ============================================================
# MemPool - arena bump 分配器
# 不支持单个 free,reset 一次性回收全部
# ============================================================
class MemPool(MemManager):
"""Arena bump 分配器。"""
offset: int # bump 游标
high_water: int # 峰值水位
def __init__(self, base: int, size: int) -> None: ...
def alloc(self, size: int) -> int: ...
def free(self, ptr: int) -> int: ...
def reset(self) -> int: ...
# ============================================================
# MemSlab - 定长块池
# arena 开头存位图,后续区域按 block_size 切分,空闲链管理
# ============================================================
class MemSlab(MemManager):
"""定长块池分配器。"""
block_size: int # 每块大小(对齐后)
block_count: int # 总块数
used_count: int # 已用块数
free_list: int # 空闲链头(指针)
alloc_map: int # 分配位图基址(指针)
alloc_map_size: int # 位图字节数
usable: int # 可用块区起始(指针)
usable_size: int # 可用块区大小
def __init__(self, base: int, size: int, block_size: int) -> None:
"""初始化定长块池。
Args:
base: 内存区起始地址
size: 内存区总大小
block_size: 每块大小
"""
...
def alloc(self, size: int) -> int: ...
def free(self, ptr: int) -> int: ...
def reset(self) -> int: ...
# ============================================================
# MemBuddy - 伙伴系统分配器
# 线程安全(自旋锁),支持合并
# ============================================================
class MemBuddy(MemManager):
"""伙伴系统分配器。
__provides__ 同时提供 '__mbuddy__' 和 '__memmgr__',
使 with MemBuddy(...) 上下文内的 __requires__=['__mbuddy__'] 类能注入。
"""
__provides__: list # ['__mbuddy__', '__memmgr__']
max_order: int # 最大阶数
free_lists: int # 空闲链头数组基址(指针)
lock_val: int # 自旋锁
usable: int # 可用区起始(指针)
usable_size: int # 可用区大小(2 的幂)
def __init__(self, base: int, size: int) -> None:
"""初始化伙伴系统。
Args:
base: 内存区起始地址
size: 内存区总大小
"""
...
def alloc(self, size: int) -> int:
"""分配内存(线程安全)。
失败时打印内存使用情况到 stderr。
"""
return 0
def free(self, ptr: int) -> int:
"""释放内存(线程安全,自动合并伙伴块)。"""
return 0
def reset(self) -> int:
"""重置(回收全部)。"""
return 0
def realloc(self, ptr: int, new_size: int) -> int:
"""重新调整大小(从块头读取旧阶数,无需 old_size)。"""
return 0
@property
def mem_size(self) -> int:
"""可用区总大小(2 的幂)。"""
return 0
def stats(self) -> int:
"""返回可用区总大小。"""
return 0
def free_count(self) -> int:
"""统计所有阶数空闲链中的块总数。"""
return 0
def free_bytes(self) -> int:
"""统计所有空闲块的总字节数。"""
return 0
def used_bytes(self) -> int:
"""已使用字节数 = 可用区总大小 - 空闲字节数。"""
return 0
def dump_stats(self, label: int) -> None:
"""打印内存使用统计到 stdout。
Args:
label: 标签字符串指针(int)
"""
...
def self_check(self) -> int:
"""验证伙伴分配器内部一致性。
Returns:
0=OK,非 0=损坏
"""
return 0
@@ -1,138 +0,0 @@
# Viper C stdint.h 类型别名存根。
# 姑息策略:所有整数/指针别名映射为 Python int,浮点映射为 float。
# 与 t.vpi 配合,提供 Win32/TransPyC 风格的大写别名及 C 标准小写 _t 别名。
from t import *
# =============================================================================
# 大写别名(Win32/TransPyC 风格)
# 注意:INTPTR/UINTPTR 在此模块中是 int*/unsigned int* 指针类型(历史命名)。
# 它们与 C 标准的 intptr_t/uintptr_t 整数类型不同,后者见下方小写 _t 区域。
# =============================================================================
INT: int # = t.CInt
INTPTR: int # = t.CInt | t.CPtr(int 指针)
BOOL: int # = t.CInt
UINT: int # = t.CUnsignedInt
UINTPTR: int # = UINT | t.CPtr
BYTE: int # = t.CUnsignedChar
BYTEPTR: int # = BYTE | t.CPtr
WORD: int # = t.CUInt16T
DWORD: int # = t.CUInt32T
QWORD: int # = t.CUInt64T
TCHAR: int # = t.CChar
CHARLIST: int # = str | t.CPtr
VOID: int # = t.CVoid
SHORT: int # = t.CShort
SHORTPTR: int # = t.CShort | t.CPtr
USHORT: int # = t.CUnsignedShort
USHORTPTR: int # = t.CUnsignedShort | t.CPtr
LONGLONG: int # = t.CLongLong
ULONGLONG: int # = t.CUnsignedLongLong
LONG: int # = t.CLong
ULONG: int # = t.CUnsignedLong
WCHAR: int # = WORD
WCHARPTR: int # = WORD | t.CPtr
CHARPTR: int # = t.CChar | t.CPtr
FSIZE_t: int # = DWORD
LBA_t: int # = DWORD
VOIDPTR: int # = t.CVoid | t.CPtr
FLOAT: float # = t.CFloat
DOUBLE: float # = t.CDouble
FLOAT8: float # = t.CFloat8T
FLOAT16: float # = t.CFloat16T
FLOAT32: float # = t.CFloat32T
FLOAT64: float # = t.CFloat64T
FLOAT128: float # = t.CFloat128T
# =============================================================================
# 定长整数大写别名
# =============================================================================
INT8: int # = t.CInt8T
INT16: int # = t.CInt16T
INT32: int # = t.CInt32T
INT64: int # = t.CInt64T
UINT8: int # = t.CUInt8T
UINT16: int # = t.CUInt16T
UINT32: int # = t.CUInt32T
UINT64: int # = t.CUInt64T
INT8PTR: int # = t.CInt8T | t.CPtr
INT16PTR: int # = t.CInt16T | t.CPtr
INT32PTR: int # = t.CInt32T | t.CPtr
INT64PTR: int # = t.CInt64T | t.CPtr
UINT8PTR: int # = t.CUInt8T | t.CPtr
UINT16PTR: int # = t.CUInt16T | t.CPtr
UINT32PTR: int # = t.CUInt32T | t.CPtr
UINT64PTR: int # = t.CUInt64T | t.CPtr
CHAR8: int # = t.CChar8T
CHAR16: int # = t.CChar16T
CHAR32: int # = t.CChar32T
CHAR8PTR: int # = t.CChar8T | t.CPtr
CHAR16PTR: int # = t.CChar16T | t.CPtr
CHAR32PTR: int # = t.CChar32T | t.CPtr
i8: int # = t.CInt8T
i16: int # = t.CInt16T
i32: int # = t.CInt32T
i64: int # = t.CInt64T
u8: int # = t.CUInt8T
u16: int # = t.CUInt16T
u32: int # = t.CUInt32T
u64: int # = t.CUInt64T
SIZE_T: int # = t.CSizeT
SSIZE_T: int # = t.CPtrDiffT
PTRDIFF_T: int # = t.CPtrDiffT
# =============================================================================
# C 标准库 <stdint.h> 类型名(小写 _t 后缀)
# 用户 `from stdint import *` 后即可直接使用 int8_t / size_t 等。
# =============================================================================
int8_t: int # = t.CInt8T
int16_t: int # = t.CInt16T
int32_t: int # = t.CInt32T
int64_t: int # = t.CInt64T
uint8_t: int # = t.CUInt8T
uint16_t: int # = t.CUInt16T
uint32_t: int # = t.CUInt32T
uint64_t: int # = t.CUInt64T
size_t: int # = t.CSizeT
ssize_t: int # = t.CPtrDiffT
ptrdiff_t: int # = t.CPtrDiffT
# intptr_t/uintptr_t 是足以容纳指针的整数类型(不是指针!)
# 与上方的 INTPTR/UINTPTR(int 指针)语义不同。
intptr_t: int # = t.CIntPtrT
uintptr_t: int # = t.CUIntPtrT
# 宽字符 / 字符类型
wchar_t: int # = t.CWCharT
char8_t: int # = t.CChar8T
char16_t: int # = t.CChar16T
char32_t: int # = t.CChar32T
# 浮点特化类型
float8_t: float # = t.CFloat8T
float16_t: float # = t.CFloat16T
float32_t: float # = t.CFloat32T
float64_t: float # = t.CFloat64T
float128_t: float # = t.CFloat128T
_Bool: int # = t.CBool
def __getattr__(name: str) -> int:
"""兜底:未声明的 stdint 别名返回 int。"""
return 0
@@ -1,113 +0,0 @@
# Viper C stdio.h 函数存根。
# 姑息策略:
# - 流指针(FILE*)映射为 bytes(姑息用 bytes 表示缓冲区指针)
# - 字符串格式参数映射为 str
# - 缓冲区参数映射为 bytes(可变缓冲)
# - 返回 t.CInt 映射为 int,t.State 映射为 None
from typing import Any
def printf(fmt: str, *args: Any) -> int:
"""格式化输出到 stdout。
Args:
fmt: 格式字符串(C 风格 %d/%s/%x/%f 等)
*args: 格式参数
Returns:
写入字符数(t.CInt),失败返回负值
"""
return 0
def fprintf(stream: bytes, fmt: str, *args: Any) -> int:
"""格式化输出到指定流。
Args:
stream: FILE* 指针(姑息用 bytes)
fmt: 格式字符串
*args: 格式参数
Returns:
写入字符数
"""
return 0
def sprintf(buf: bytes, fmt: str, *args: Any) -> int:
"""格式化写入到缓冲区(不检查边界,慎用)。
Args:
buf: 目标缓冲区(bytes,可变)
fmt: 格式字符串
*args: 格式参数
Returns:
写入字符数
"""
return 0
def snprintf(buf: bytes, size: int, fmt: str, *args: Any) -> int:
"""格式化写入到缓冲区(带大小限制)。
Args:
buf: 目标缓冲区
size: 缓冲区最大容量
fmt: 格式字符串
*args: 格式参数
Returns:
本应写入的字符数(可能 >= size)
"""
return 0
def puts(s: str) -> int:
"""输出字符串到 stdout 并追加换行。
Args:
s: 要输出的字符串
Returns:
成功返回非负值,失败返回 EOF
"""
return 0
def fputs(s: str, stream: bytes) -> int:
"""输出字符串到指定流(不追加换行)。
Args:
s: 要输出的字符串
stream: FILE* 指针
Returns:
成功返回非负值,失败返回 EOF
"""
return 0
def fgets(buf: bytes, size: int, stream: bytes) -> bytes:
"""从流读取一行。
Args:
buf: 目标缓冲区
size: 缓冲区最大容量
stream: FILE* 指针
Returns:
成功返回 buf 指针,失败或 EOF 返回 None
"""
...
def fflush(stream: bytes) -> int:
"""刷新流缓冲区。
Args:
stream: FILE* 指针,传 0(NULL)刷新所有输出流
Returns:
成功返回 0,失败返回 EOF
"""
return 0
# 标准流指针(全局变量,仅声明供 printf 等函数使用)
stdin: bytes = 0 # 标准输入流
stdout: bytes = 0 # 标准输出流
stderr: bytes = 0 # 标准错误流
@@ -1,121 +0,0 @@
# Viper C stdlib.h 函数存根。
# 姑息策略:
# - malloc/calloc/realloc 返回 int(指针整数,NULL=0 表示失败)
# - free 接受 int(指针)
# - system 返回 int(命令退出码)
from stdint import *
def malloc(size: int) -> int:
"""分配 size 字节的内存。
Args:
size: 要分配的字节数
Returns:
成功返回指向分配内存的指针(int),失败返回 0(NULL)
"""
return 0
def calloc(nmemb: int, size: int) -> int:
"""分配 nmemb 个 size 字节的内存并清零。
Args:
nmemb: 元素个数
size: 每个元素的字节数
Returns:
成功返回指针(int),失败返回 0
"""
return 0
def realloc(p: int, size: int) -> int:
"""重新调整已分配内存的大小。
Args:
p: 原指针(int),可为 0(NULL)表示新分配
size: 新大小
Returns:
成功返回新指针(int),失败返回 0(原内存不变)
"""
return 0
def free(p: int) -> None:
"""释放已分配的内存。
Args:
p: malloc/calloc/realloc 返回的指针,传 0(NULL)无操作
"""
...
def system(cmd: str) -> int:
"""执行系统命令。
Args:
cmd: 命令字符串(C 风格 const char*)
Returns:
命令退出码(平台相关),cmd 为 None 时返回非 0 表示 shell 可用
"""
return 0
def exit(status: int) -> None:
"""终止进程。
Args:
status: 退出码(0 表示成功)
"""
...
def abort() -> None:
"""异常终止进程(触发 SIGABRT)。"""
...
def atof(s: str) -> float:
"""字符串转 double。
Args:
s: 数字字符串
Returns:
解析得到的浮点数
"""
return 0.0
def atoi(s: str) -> int:
"""字符串转 int。
Args:
s: 数字字符串
Returns:
解析得到的整数
"""
return 0
def atol(s: str) -> int:
"""字符串转 long。
Args:
s: 数字字符串
Returns:
解析得到的整数
"""
return 0
def qsort(base: int, nmemb: int, size: int, compar: int) -> None:
"""快速排序。
Args:
base: 数组基址指针(int)
nmemb: 元素个数
size: 每个元素字节数
compar: 比较函数指针(int),签名 int (*)(const void*, const void*)
"""
...
@@ -1,218 +0,0 @@
# Viper C string.h 函数存根。
# 姑息策略:
# - 字符串参数映射为 str
# - 内存缓冲区指针映射为 int(指针整数)
# - 内存函数返回指针(int)
# - 长度/比较返回 int
from typing import Any
# =============================================================================
# 字符串复制
# =============================================================================
def strcpy(dest: str, src: str) -> str:
"""复制 src 到 dest(含终止符)。
Returns:
dest 指针
"""
...
def strncpy(dest: str, src: str, n: int) -> str:
"""复制 src 前 n 个字符到 dest。
不足 n 时用 \\0 填充,超过 n 不追加终止符。
Args:
n: 最大复制字节数
Returns:
dest 指针
"""
...
# =============================================================================
# 字符串拼接
# =============================================================================
def strcat(dest: str, src: str) -> str:
"""将 src 追加到 dest 末尾。
Returns:
dest 指针
"""
...
def strncat(dest: str, src: str, n: int) -> str:
"""将 src 前 n 个字符追加到 dest 末尾。"""
...
# =============================================================================
# 字符串比较
# =============================================================================
def strcmp(str1: str, str2: str) -> int:
"""比较两个字符串。
Returns:
< 0 表示 str1 < str2,= 0 表示相等,> 0 表示 str1 > str2
"""
return 0
def strncmp(str1: str, str2: str, n: int) -> int:
"""比较两个字符串前 n 个字符。"""
return 0
def samestr(str1: str, str2: str) -> bool:
"""Viper 扩展:直接 == 比较。"""
return False
# =============================================================================
# 字符串长度
# =============================================================================
def strlen(src: str) -> int:
"""返回字符串长度(不含终止符)。"""
return 0
# =============================================================================
# 字符查找
# =============================================================================
def strchr(s: str, cr: int) -> str:
"""在 s 中查找字符 cr 第一次出现的位置。
Args:
cr: 字符的 ASCII 码(int)
Returns:
指向该字符的指针,未找到返回 None
"""
...
def strrchr(s: str, cr: int) -> str:
"""在 s 中查找字符 cr 最后一次出现的位置。
Returns:
指向该字符的指针,未找到返回 None
"""
...
def strstr(s: str, needle: str) -> str:
"""在 s 中查找子串 needle 第一次出现的位置。
Returns:
指向子串起始的指针,未找到返回 None
"""
...
def strspn(s: str, skip: str = " ") -> int:
"""返回 s 开头连续属于 skip 的字符数。"""
return 0
# =============================================================================
# 内存操作
# =============================================================================
def memset(ptr: int, value: int, num: int) -> int:
"""将 ptr 指向的 num 字节内存全部设置为 value。
Args:
ptr: 内存指针(int)
value: 填充值(取低 8 位)
num: 字节数
Returns:
ptr 指针
"""
return 0
def memset32(ptr: int, value: int, count: int) -> int:
"""将 ptr 指向的 count 个 32 位整数全部设置为 value。
Args:
ptr: 内存指针(int)
value: 32 位填充值
count: 32 位整数个数
Returns:
ptr 指针
"""
return 0
def memcpy(dest: int, src: int, num: int) -> int:
"""从 src 复制 num 字节到 dest(不处理重叠)。
Returns:
dest 指针
"""
return 0
def memmove(dest: int, src: int, num: int) -> int:
"""从 src 复制 num 字节到 dest(处理重叠)。
Returns:
dest 指针
"""
return 0
def memcmp(ptr1: int, ptr2: int, n: int) -> int:
"""比较两块内存前 n 字节。
Returns:
< 0 表示 ptr1 < ptr2,= 0 表示相等,> 0 表示 ptr1 > ptr2
"""
return 0
# =============================================================================
# 字符串转数字(Viper 实现放在 string.py 中)
# =============================================================================
def atoi(src: str) -> int:
"""字符串转 int(支持前导空白和符号)。"""
return 0
def atoll(src: str) -> int:
"""字符串转 long long。"""
return 0
def atof(src: str) -> float:
"""字符串转 double(支持整数/小数/指数部分)。"""
return 0.0
def split(s: str, delim: str, result: list) -> int:
"""Viper 扩展:按单字符分隔符切分字符串。
Args:
s: 待切分字符串
delim: 单字符分隔符
result: 结果数组(str 指针数组),调用方需保证容量
Returns:
切分得到的 token 数
"""
return 0
# =============================================================================
# 字符集常量
# =============================================================================
ascii_lowercase: str = "abcdefghijklmnopqrstuvwxyz"
ascii_uppercase: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
ascii_letters: str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
digits: str = "0123456789"
hexdigits: str = "0123456789abcdefABCDEF"
octdigits: str = "01234567"
punctuation: str = "!\"#$%&'()*+,-./:;<=>?@[]^_`{|}~"
whitespace: str = " \t\n\r\f\v"
@@ -1,101 +0,0 @@
# Viper sys 模块存根。
# 提供 C 标准库 IO 声明、平台信息、进程信息、命令行参数访问。
# 姑息策略:
# - _mbuddy 为模块级全局 MemBuddy 指针(int)
# - 命令行 argv 数组指针为 int(char**)
# - exit 终止进程返回 None
import t
import memhub
from stdint import *
# 模块级全局 MBuddy 指针(由用户在 main 中赋值初始化)
_mbuddy: int # memhub.MemBuddy | t.CPtr
# =============================================================================
# C 标准库 IO 声明(从 sys 模块转发)
# =============================================================================
def fgets(buf: int, size: int, stream: int) -> int:
"""从流读取一行(C stdio 声明)。
Args:
buf: 目标缓冲区指针(int)
size: 缓冲区最大容量
stream: FILE* 指针(int)
Returns:
成功返回 buf 指针,失败返回 0(NULL)
"""
return 0
def fflush(stream: int) -> int:
"""刷新流缓冲区(C stdio 声明)。
Args:
stream: FILE* 指针(int),传 0 刷新所有输出流
Returns:
成功返回 0,失败返回 EOF
"""
return 0
def exit(status: int) -> None:
"""终止进程(刷新缓冲区后终止,跨平台)。
Args:
status: 退出码(0 表示成功)
"""
...
# =============================================================================
# 平台信息
# =============================================================================
# 最大整数值(64 位平台 ssize_t 上限)
maxsize: int = 9223372036854775807
def platform() -> str:
"""返回平台标识字符串。
Returns:
'win32' 或 'linux'
"""
return ""
# =============================================================================
# 进程信息
# =============================================================================
def get_pid() -> int:
"""返回当前进程 ID。"""
return 0
# =============================================================================
# 命令行参数(argv)
# =============================================================================
# 全局 argv 状态(首次访问时初始化)
_argc: int = 0
# _argv 是指针数组(char**),姑息映射为 int
_argv: int
def argc() -> int:
"""返回命令行参数个数。首次调用时自动初始化。"""
return 0
def argv(index: int) -> str:
"""返回第 index 个命令行参数(index 从 0 开始)。
首次调用时自动初始化。索引越界返回 None。
Args:
index: 参数索引(0 = 程序名)
Returns:
参数字符串,越界返回 None
"""
return ""
@@ -1,8 +1,9 @@
# Viper 类型系统模块 t 的存根。
#
# 姑息策略(完善版):
# - 基本数值/字符类型使用 TypeAlias 别名(等价 Python 内置类型),
# 使 `k: t.CInt = 1` 合法(1 是 int,CInt 别名 int)
# 类型策略:
# - 所有 C 类型作为独立 class 继承 CType,保留类型语义信息(绿色高亮)。
# - typeEvaluator 中的 Viper 扩展允许 int/float/str/bool 值赋给 CType 子类,
# 使 `k: t.CInt = 1` 合法(1 是 int,CInt 在底层等价 int)。
# - 指针/修饰符/命名类型作为独立 class 继承 CType,
# 保持"类型"语义(绿色高亮)和联合类型 `T | t.CPtr` 支持
# - CPtr 支持泛型下标 `t.CPtr[t.CInt]`
@@ -15,6 +16,7 @@ from typing import Any, Generic, Optional, Type, TypeAlias, TypeVar
from typing import Callable as CallableT
T = TypeVar('T')
N = TypeVar('N')
# =============================================================================
@@ -57,90 +59,280 @@ class CTypeDefault(CType):
# =============================================================================
# 基本整数类型(TypeAlias 别名,等价 int)
# 基本整数类型(独立 class,继承 CType)
# Viper 语义:C 整数类型在底层等价于 int,但作为独立类型保留语义信息。
# typeEvaluator 中的 Viper 扩展允许 int 值赋给 CType 子类。
# =============================================================================
CChar: TypeAlias = int
CShort: TypeAlias = int
CInt: TypeAlias = int
CLong: TypeAlias = int
CLongLong: TypeAlias = int
CSignedChar: TypeAlias = int
CUnsignedChar: TypeAlias = int
CUnsignedShort: TypeAlias = int
CUnsignedInt: TypeAlias = int
CUnsignedLong: TypeAlias = int
CUnsignedLongLong: TypeAlias = int
class CChar(CType):
"""char 类型。"""
pass
class CShort(CType):
"""short 类型。"""
pass
class CInt(CType):
"""int 类型。"""
pass
class CLong(CType):
"""long 类型。"""
pass
class CLongLong(CType):
"""long long 类型。"""
pass
class CSignedChar(CType):
"""signed char 类型。"""
pass
class CUnsignedChar(CType):
"""unsigned char 类型。"""
pass
class CUnsignedShort(CType):
"""unsigned short 类型。"""
pass
class CUnsignedInt(CType):
"""unsigned int 类型。"""
pass
class CUnsignedLong(CType):
"""unsigned long 类型。"""
pass
class CUnsignedLongLong(CType):
"""unsigned long long 类型。"""
pass
# 固定宽度整数
CInt8T: TypeAlias = int
CInt16T: TypeAlias = int
CInt32T: TypeAlias = int
CInt64T: TypeAlias = int
CUInt8T: TypeAlias = int
CUInt16T: TypeAlias = int
CUInt32T: TypeAlias = int
CUInt64T: TypeAlias = int
class CInt8T(CType):
"""int8_t 类型。"""
pass
class CInt16T(CType):
"""int16_t 类型。"""
pass
class CInt32T(CType):
"""int32_t 类型。"""
pass
class CInt64T(CType):
"""int64_t 类型。"""
pass
class CUInt8T(CType):
"""uint8_t 类型。"""
pass
class CUInt16T(CType):
"""uint16_t 类型。"""
pass
class CUInt32T(CType):
"""uint32_t 类型。"""
pass
class CUInt64T(CType):
"""uint64_t 类型。"""
pass
# 最小/最快宽度整数
CIntLeast8T: TypeAlias = int
CIntLeast16T: TypeAlias = int
CIntLeast32T: TypeAlias = int
CIntLeast64T: TypeAlias = int
CIntFast8T: TypeAlias = int
CIntFast16T: TypeAlias = int
CIntFast32T: TypeAlias = int
CIntFast64T: TypeAlias = int
CUIntLeast8T: TypeAlias = int
CUIntLeast16T: TypeAlias = int
CUIntLeast32T: TypeAlias = int
CUIntLeast64T: TypeAlias = int
CUIntFast8T: TypeAlias = int
CUIntFast16T: TypeAlias = int
CUIntFast32T: TypeAlias = int
CUIntFast64T: TypeAlias = int
class CIntLeast8T(CType):
"""int_least8_t 类型。"""
pass
class CIntLeast16T(CType):
"""int_least16_t 类型。"""
pass
class CIntLeast32T(CType):
"""int_least32_t 类型。"""
pass
class CIntLeast64T(CType):
"""int_least64_t 类型。"""
pass
class CIntFast8T(CType):
"""int_fast8_t 类型。"""
pass
class CIntFast16T(CType):
"""int_fast16_t 类型。"""
pass
class CIntFast32T(CType):
"""int_fast32_t 类型。"""
pass
class CIntFast64T(CType):
"""int_fast64_t 类型。"""
pass
class CUIntLeast8T(CType):
"""uint_least8_t 类型。"""
pass
class CUIntLeast16T(CType):
"""uint_least16_t 类型。"""
pass
class CUIntLeast32T(CType):
"""uint_least32_t 类型。"""
pass
class CUIntLeast64T(CType):
"""uint_least64_t 类型。"""
pass
class CUIntFast8T(CType):
"""uint_fast8_t 类型。"""
pass
class CUIntFast16T(CType):
"""uint_fast16_t 类型。"""
pass
class CUIntFast32T(CType):
"""uint_fast32_t 类型。"""
pass
class CUIntFast64T(CType):
"""uint_fast64_t 类型。"""
pass
# 最大宽度整数
CIntMaxT: TypeAlias = int
CUIntMaxT: TypeAlias = int
class CIntMaxT(CType):
"""intmax_t 类型。"""
pass
class CUIntMaxT(CType):
"""uintmax_t 类型。"""
pass
# 平台相关整数
CSizeT: TypeAlias = int
CIntPtrT: TypeAlias = int
CUIntPtrT: TypeAlias = int
CPtrDiffT: TypeAlias = int
class CSizeT(CType):
"""size_t 类型。"""
pass
class CIntPtrT(CType):
"""intptr_t 类型。"""
pass
class CUIntPtrT(CType):
"""uintptr_t 类型。"""
pass
class CPtrDiffT(CType):
"""ptrdiff_t 类型。"""
pass
# 布尔
CBool: TypeAlias = int
class CBool(CType):
"""bool 类型(_Bool)。"""
pass
# 宽字符
CWCharT: TypeAlias = int
CChar8T: TypeAlias = int
CChar16T: TypeAlias = int
CChar32T: TypeAlias = int
class CWCharT(CType):
"""wchar_t 类型。"""
pass
# LLVM 简写(直接作为类型别名,等价于固定宽度整数)
i1: TypeAlias = int
i8: TypeAlias = int
i16: TypeAlias = int
i32: TypeAlias = int
i64: TypeAlias = int
u1: TypeAlias = int
u8: TypeAlias = int
u16: TypeAlias = int
u32: TypeAlias = int
u64: TypeAlias = int
class CChar8T(CType):
"""char8_t 类型。"""
pass
class CChar16T(CType):
"""char16_t 类型。"""
pass
class CChar32T(CType):
"""char32_t 类型。"""
pass
# LLVM 简写(独立 class,等价于固定宽度整数)
class i1(CType):
"""LLVM i1 类型(1 位整数)。"""
pass
class i8(CType):
"""LLVM i8 类型(8 位整数)。"""
pass
class i16(CType):
"""LLVM i16 类型(16 位整数)。"""
pass
class i32(CType):
"""LLVM i32 类型(32 位整数)。"""
pass
class i64(CType):
"""LLVM i64 类型(64 位整数)。"""
pass
class u1(CType):
"""LLVM u1 类型(1 位无符号整数)。"""
pass
class u8(CType):
"""LLVM u8 类型(8 位无符号整数)。"""
pass
class u16(CType):
"""LLVM u16 类型(16 位无符号整数)。"""
pass
class u32(CType):
"""LLVM u32 类型(32 位无符号整数)。"""
pass
class u64(CType):
"""LLVM u64 类型(64 位无符号整数)。"""
pass
# =============================================================================
# 浮点类型(TypeAlias 别名,等价 float)
# 浮点类型(独立 class,继承 CType)
# Viper 语义:C 浮点类型在底层等价于 float,但作为独立类型保留语义信息。
# =============================================================================
CFloat: TypeAlias = float
CDouble: TypeAlias = float
CFloat8T: TypeAlias = float
CFloat16T: TypeAlias = float
CFloat32T: TypeAlias = float
CFloat64T: TypeAlias = float
CFloat128T: TypeAlias = float
class CFloat(CType):
"""float 类型。"""
pass
class CDouble(CType):
"""double 类型。"""
pass
class CFloat8T(CType):
"""_Float8 类型。"""
pass
class CFloat16T(CType):
"""_Float16 类型。"""
pass
class CFloat32T(CType):
"""_Float32 类型。"""
pass
class CFloat64T(CType):
"""_Float64 类型。"""
pass
class CFloat128T(CType):
"""_Float128 类型。"""
pass
# =============================================================================
@@ -181,14 +373,15 @@ class CArrayPtr(CType):
# =============================================================================
# 数组类型(支持下标)
# =============================================================================
class CArray(CType):
class CArray(CType, Generic[T, N]):
"""栈上固定数组类型注解。
用法: names: t.CArray[VOIDPTR, 32] # void*[32]
data: t.CArray[t.CInt, 64] # int[64]
T 为元素类型,N 为数组长度(整数)。
"""
def __class_getitem__(cls, item: Any) -> type: ...
def __getitem__(self, index: int) -> Any: ...
def __setitem__(self, index: int, value: Any) -> None: ...
def __getitem__(self, index: int) -> T: ...
def __setitem__(self, index: int, value: T) -> None: ...
# =============================================================================
@@ -625,9 +818,9 @@ class ASM_DESCR:
# =============================================================================
# 函数指针
# =============================================================================
class Callable(CType):
"""函数指针类型。"""
pass
# Viper 的 Callable 等价于 typing.Callable,支持 Callable[[], TReturn] 订阅语法。
# 直接赋值(不加 TypeAlias 注解),让 Pyright 识别为 typing.Callable 别名。
Callable = CallableT
# =============================================================================
@@ -1,93 +0,0 @@
# Viper 标准库扩展 viperlib 存根。
# 提供 snprintf/sprintf/vsnprintf 等 C 风格格式化函数的纯 Viper 实现。
# 姑息策略:
# - 缓冲区指针映射为 int(指针整数)
# - 格式字符串映射为 str
# - va_list 参数列表映射为 int(指针整数)
# - 返回 t.CInt 映射为 int
from typing import Any
# 临时缓冲区大小(vsnprintf 内部数字转换用)
TEMP_BUF_SIZE: int = 68
def get_digit_count(num: int, base: int) -> int:
"""计算 num 在指定进制下的位数。
Args:
num: 无符号整数
base: 进制(2/8/10/16)
Returns:
位数
"""
return 0
def sprintf(buf: int, rule: str, *args: Any) -> None:
"""格式化写入到缓冲区(不检查边界)。
内部调用 vsnprintf,size 设为 INT_MAX。
Args:
buf: 目标缓冲区指针(int)
rule: 格式字符串
*args: 格式参数
"""
...
def vsprintf(buf: int, rule: str, *args: Any) -> int:
"""可变参数版本的 sprintf。
Args:
buf: 目标缓冲区指针(int)
rule: 格式字符串
*args: 格式参数
Returns:
写入字符数
"""
return 0
def snprintf(buf: int, size: int, fmt: str, *args: Any) -> int:
"""格式化写入到缓冲区(带大小限制)。
Args:
buf: 目标缓冲区指针(int)
size: 缓冲区最大容量
fmt: 格式字符串
*args: 格式参数
Returns:
本应写入的字符数
"""
return 0
def vsnprintf(buf: int, size: int, fmt: str, ap: int) -> int:
"""可变参数版本的 snprintf。
支持的格式说明符:%c %s %d %i %u %x %X %o %b %p %f %F %e %E %g %G %a %A %n %%
支持的修饰符:- 0 + 空格 # 宽度 .精度 h hh l ll z j t
Args:
buf: 目标缓冲区指针(int)
size: 缓冲区最大容量
fmt: 格式字符串
ap: va_list 参数列表指针(int)
Returns:
写入字符数
"""
return 0
def _check_special_float(fv: float) -> int:
"""检测浮点特殊值(IEEE 754)。
Args:
fv: 待检测的 double 值
Returns:
0=normal, 1=+inf, 2=-inf, 3=nan
"""
return 0
+62
View File
@@ -54,6 +54,68 @@
"path": "./syntaxes/viper.tmLanguage.json"
}
],
"configurationDefaults": {
"[viper]": {
"editor.semanticHighlighting.enabled": true
}
},
"semanticTokenScopes": [
{
"language": "viper",
"scopes": {
"keyword": [
"keyword.control",
"keyword"
],
"builtin": [
"constant.language",
"variable.language",
"support.type.builtin",
"support.function.builtin"
],
"variable": [
"variable"
],
"function": [
"entity.name.function"
],
"class": [
"entity.name.class",
"entity.name.type"
],
"type": [
"entity.name.type",
"support.type"
],
"namespace": [
"entity.name.namespace"
],
"string": [
"string"
],
"number": [
"constant.numeric"
],
"comment": [
"comment"
],
"decorator": [
"entity.name.function.decorator",
"meta.decorator"
],
"parameter": [
"variable.parameter"
],
"property": [
"variable.other.property",
"variable.other.member"
],
"undefined": [
"variable"
]
}
}
],
"commands": [
{
"command": "viper.organizeimports",
@@ -3,824 +3,125 @@
"scopeName": "source.viper",
"patterns": [
{
"include": "#statement"
"include": "#comment"
},
{
"include": "#keyword"
},
{
"include": "#string"
},
{
"include": "#number"
},
{
"include": "#decorator"
}
],
"repository": {
"statement": {
"comment": {
"patterns": [
{
"include": "#line-comment"
},
{
"include": "#type-annotation-string-single"
},
{
"include": "#type-annotation-string-double"
},
{
"include": "#string-quoted-double-block"
},
{
"include": "#string-quoted-single-block"
},
{
"include": "#string-quoted-double"
},
{
"include": "#string-quoted-single"
},
{
"include": "#fstring-double-block"
},
{
"include": "#fstring-single-block"
},
{
"include": "#fstring-double"
},
{
"include": "#fstring-single"
},
{
"include": "#literal"
},
{
"include": "#decorator"
},
{
"include": "#function-declaration"
},
{
"include": "#class-declaration"
},
{
"include": "#import-statement"
},
{
"include": "#reserved"
},
{
"include": "#builtin-functions"
},
{
"include": "#module-access"
},
{
"include": "#class-call"
},
{
"include": "#function-call"
},
{
"include": "#builtin-types"
},
{
"include": "#builtin-constants"
},
{
"include": "#magic-names"
},
{
"include": "#language-variable"
},
{
"include": "#type-name"
},
{
"include": "#variable"
},
{
"include": "#illegal"
"name": "comment.line.number-sign.viper",
"match": "#.*$"
}
]
},
"line-comment": {
"name": "comment.line.number-sign.viper",
"match": "(\\#).*$",
"captures": {
"1": {
"name": "punctuation.definition.comment.viper"
}
}
},
"string-quoted-double-block": {
"name": "string.quoted.double.block.viper",
"begin": "(\"\"\")",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.viper"
}
},
"end": "(\"\"\")",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.viper"
}
},
"keyword": {
"patterns": [
{
"include": "#escape-sequence-unicode"
"name": "keyword.control.flow.viper",
"match": "\\b(if|elif|else|while|for|in|return|break|continue|pass|raise|try|except|finally|with|as|import|from|yield|async|await|del|assert|lambda|match|case)\\b"
},
{
"include": "#escape-sequence"
"name": "storage.type.function.viper",
"match": "\\bdef\\b"
},
{
"include": "#string-formatting"
"name": "storage.type.class.viper",
"match": "\\bclass\\b"
},
{
"name": "keyword.other.viper",
"match": "\\b(global|nonlocal|is|not|and|or|type)\\b"
},
{
"name": "constant.language.null.viper",
"match": "\\bNone\\b"
},
{
"name": "constant.language.boolean.viper",
"match": "\\b(True|False)\\b"
}
]
},
"string-quoted-single-block": {
"name": "string.quoted.single.block.viper",
"begin": "(''')",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.viper"
}
},
"end": "(''')",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.viper"
}
},
"string": {
"patterns": [
{
"include": "#escape-sequence-unicode"
},
{
"include": "#escape-sequence"
},
{
"include": "#string-formatting"
}
]
},
"string-quoted-double": {
"name": "string.quoted.double.viper",
"begin": "(\")",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.viper"
}
},
"end": "(\")",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.viper"
}
},
"patterns": [
{
"include": "#escape-sequence-unicode"
},
{
"include": "#escape-sequence"
},
{
"include": "#string-formatting"
}
]
},
"string-quoted-single": {
"name": "string.quoted.single.viper",
"begin": "(')",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.viper"
}
},
"end": "(')",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.viper"
}
},
"patterns": [
{
"include": "#escape-sequence-unicode"
},
{
"include": "#escape-sequence"
},
{
"include": "#string-formatting"
}
]
},
"fstring-double-block": {
"name": "string.quoted.double.block.viper meta.fstring.viper",
"begin": "([fFrR]b?|b[fFrR])(\"\"\")",
"beginCaptures": {
"1": {
"name": "storage.type.string.viper"
},
"2": {
"name": "punctuation.definition.string.begin.viper"
}
},
"end": "(\"\"\")",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.viper"
}
},
"patterns": [
{
"include": "#fstring-content"
}
]
},
"fstring-single-block": {
"name": "string.quoted.single.block.viper meta.fstring.viper",
"begin": "([fFrR]b?|b[fFrR])(''')",
"beginCaptures": {
"1": {
"name": "storage.type.string.viper"
},
"2": {
"name": "punctuation.definition.string.begin.viper"
}
},
"end": "(''')",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.viper"
}
},
"patterns": [
{
"include": "#fstring-content"
}
]
},
"fstring-double": {
"name": "string.quoted.double.viper meta.fstring.viper",
"begin": "([fFrR]b?|b[fFrR])(\")",
"beginCaptures": {
"1": {
"name": "storage.type.string.viper"
},
"2": {
"name": "punctuation.definition.string.begin.viper"
}
},
"end": "(\")",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.viper"
}
},
"patterns": [
{
"include": "#fstring-content"
}
]
},
"fstring-single": {
"name": "string.quoted.single.viper meta.fstring.viper",
"begin": "([fFrR]b?|b[fFrR])(')",
"beginCaptures": {
"1": {
"name": "storage.type.string.viper"
},
"2": {
"name": "punctuation.definition.string.begin.viper"
}
},
"end": "(')",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.viper"
}
},
"patterns": [
{
"include": "#fstring-content"
}
]
},
"fstring-content": {
"patterns": [
{
"include": "#escape-sequence-unicode"
},
{
"include": "#escape-sequence"
},
{
"name": "meta.interpolation.viper",
"begin": "(\\{)",
"beginCaptures": {
"1": {
"name": "keyword.control.decorator.viper"
}
},
"end": "(\\})",
"endCaptures": {
"1": {
"name": "keyword.control.decorator.viper"
}
},
"contentName": "meta.embedded",
"name": "string.quoted.double.block.viper",
"begin": "\"\"\"",
"end": "\"\"\"",
"patterns": [
{
"include": "#literal"
},
"include": "#fstring-interpolation"
}
]
},
{
"name": "string.quoted.single.block.viper",
"begin": "'''",
"end": "'''",
"patterns": [
{
"include": "#reserved"
},
"include": "#fstring-interpolation"
}
]
},
{
"name": "string.quoted.double.viper",
"begin": "\"",
"end": "\"",
"patterns": [
{
"include": "#builtin-functions"
},
"include": "#fstring-interpolation"
}
]
},
{
"name": "string.quoted.single.viper",
"begin": "'",
"end": "'",
"patterns": [
{
"include": "#builtin-types"
},
{
"include": "#builtin-constants"
},
{
"include": "#language-variable"
},
{
"include": "#module-access"
},
{
"include": "#class-call"
},
{
"include": "#function-call"
},
{
"include": "#string-quoted-single"
},
{
"include": "#string-quoted-double"
},
{
"include": "#fstring-interpolation-punctuation"
},
{
"include": "#variable"
"include": "#fstring-interpolation"
}
]
}
]
},
"fstring-interpolation-punctuation": {
"fstring-interpolation": {
"patterns": [
{
"name": "keyword.operator.assignment.viper",
"match": ":="
},
{
"name": "keyword.other.conversion.viper",
"match": "![rsa]"
},
{
"name": "punctuation.separator.format-spec.viper",
"match": ":"
},
{
"name": "meta.brace.round.viper",
"match": "[()]"
},
{
"name": "meta.brace.square.viper",
"match": "[\\[\\]]"
},
{
"name": "punctuation.separator.arguments.viper",
"match": ","
},
{
"name": "punctuation.accessor.viper",
"match": "\\."
},
{
"name": "keyword.operator.assignment.viper",
"match": "="
},
{
"name": "keyword.operator.arithmetic.viper",
"match": "[+\\-*/%]"
},
{
"name": "keyword.operator.comparison.viper",
"match": "[<>=!]=|[<>]"
"name": "meta.embedded.interpolation.viper",
"match": "\\{[^}]*\\}"
}
]
},
"escape-sequence-unicode": {
"name": "constant.character.escape.viper",
"match": "\\\\([uU][0-9A-Fa-f]{4,8}|N\\{[^}]+\\})"
},
"escape-sequence": {
"name": "constant.character.escape.viper",
"match": "\\\\(['\"\\\\\\n\\r\\t\\abfv0-7]|x[0-9A-Fa-f]{2})"
},
"string-formatting": {
"name": "constant.other.placeholder.viper",
"match": "%(\\([^)]*\\))?[+#-]*(\\d+|\\*)?(?:\\.(\\d+|\\*))?[hlL]?[diouxXeEfFgGcrsa%]"
},
"literal": {
"number": {
"patterns": [
{
"name": "constant.language.viper",
"match": "\\b(True|False|None|NotImplemented|Ellipsis|__debug__)\\b"
},
{
"name": "constant.numeric.integer.hexadecimal.viper",
"match": "\\b0[xX][_0-9A-Fa-f]+\\b"
},
{
"name": "constant.numeric.integer.octal.viper",
"match": "\\b0[oO][_0-7]+\\b"
},
{
"name": "constant.numeric.integer.binary.viper",
"match": "\\b0[bB][_01]+\\b"
},
{
"name": "constant.numeric.float.viper",
"match": "(?x)\n (?<!\\.)\n (?:\n (?: \\d[\\d_]* \\.[\\d_]* (?:[eE][+-]?\\d+)? )\n | (?: \\.\\d[\\d_]* (?:[eE][+-]?\\d+)? )\n | (?: \\d[\\d_]* [eE][+-]?\\d+ )\n )\n ([jJ])?"
},
{
"name": "constant.numeric.integer.decimal.viper",
"match": "\\b[0-9][\\d_]*\\b"
"name": "constant.numeric.viper",
"match": "\\b(0x[0-9a-fA-F]+|0o[0-7]+|0b[01]+|\\d+\\.?\\d*([eE][+-]?\\d+)?)\\b"
}
]
},
"decorator": {
"name": "meta.function.decorator.viper",
"match": "(?x)\n ^[ \\t]*\n (@)\n ([A-Za-z_][\\w.]*)\n",
"captures": {
"1": {
"name": "keyword.control.decorator.viper"
},
"2": {
"name": "entity.name.function.decorator.viper"
}
}
},
"function-declaration": {
"name": "meta.function.viper",
"begin": "(?x)\n ^[ \\t]*\n (?:\\b(async)\\s+)?\n (def)\\s+\n ([A-Za-z_][\\w]*)\n",
"beginCaptures": {
"1": {
"name": "storage.type.async.viper"
},
"2": {
"name": "storage.type.function.viper"
},
"3": {
"name": "entity.name.function.viper"
}
},
"end": "(?x)\n (?= \\s* : \\s* (?: $ | \\# ) )\n",
"patterns": [
{
"include": "#parameters"
},
{
"include": "#return-type"
},
{
"include": "#line-comment"
"name": "entity.name.function.decorator.viper",
"match": "@[a-zA-Z_][a-zA-Z0-9_.]*"
}
]
},
"class-declaration": {
"name": "meta.class.viper",
"begin": "(?x)\n ^[ \\t]*\n (class)\\s+\n ([A-Za-z_][\\w]*)\n",
"beginCaptures": {
"1": {
"name": "storage.type.class.viper"
},
"2": {
"name": "entity.name.type.class.viper"
}
},
"end": "(?x)\n (?= \\s* : \\s* (?: $ | \\# ) )\n",
"patterns": [
{
"name": "punctuation.definition.inheritance.begin.viper",
"match": "\\("
},
{
"name": "punctuation.definition.inheritance.end.viper",
"match": "\\)"
},
{
"include": "#builtin-types"
},
{
"include": "#line-comment"
}
]
},
"parameters": {
"patterns": [
{
"name": "keyword.operator.unpacking.arguments.viper",
"match": "(\\*\\*|\\*)"
},
{
"include": "#literal"
},
{
"include": "#builtin-types"
},
{
"include": "#builtin-constants"
},
{
"include": "#type-annotation-string-single"
},
{
"include": "#type-annotation-string-double"
},
{
"name": "variable.parameter.viper",
"match": "\\b[A-Za-z_][\\w]*\\b"
},
{
"name": "keyword.operator.assignment.viper",
"match": "="
},
{
"name": "keyword.operator.arrow.viper",
"match": "->"
},
{
"name": "punctuation.separator.parameters.viper",
"match": ","
}
]
},
"return-type": {
"patterns": [
{
"include": "#return-type-string-single"
},
{
"include": "#return-type-string-double"
},
{
"name": "keyword.operator.arrow.viper",
"match": "->"
},
{
"include": "#builtin-types"
},
{
"include": "#type-annotation-content"
}
]
},
"reserved": {
"patterns": [
{
"name": "keyword.control.flow.viper",
"match": "\\b(elif|else|for|if|while|return|yield|with|try|finally|except|raise|break|continue|pass|match|case)\\b"
},
{
"name": "keyword.control.import.viper",
"match": "\\b(import|from|as)\\b"
},
{
"name": "keyword.control.flow.viper",
"match": "\\b(and|or|not|in|is)\\b"
},
{
"name": "storage.type.function.viper",
"match": "\\b(def|lambda)\\b"
},
{
"name": "storage.type.class.viper",
"match": "\\b(class)\\b"
},
{
"name": "storage.modifier.async.viper",
"match": "\\b(async|await)\\b"
},
{
"name": "storage.modifier.declaration.viper",
"match": "\\b(global|nonlocal|del|assert)\\b"
}
]
},
"builtin-functions": {
"name": "support.function.builtin.viper",
"match": "(?x)\n \\b(\n __import__|abs|aiter|all|anext|any|ascii|bin|bool|breakpoint|bytearray|\n bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|\n enumerate|eval|exec|exit|filter|float|format|frozenset|getattr|globals|\n hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|\n list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|\n property|quit|range|repr|reversed|round|set|setattr|slice|sorted|\n staticmethod|str|sum|super|tuple|type|vars|zip\n )\\b(?=\\s*\\()"
},
"function-call": {
"name": "meta.function-call.viper",
"match": "\\b([A-Za-z_][\\w]*)\\s*(?=\\()",
"captures": {
"1": {
"name": "entity.name.function.viper"
}
}
},
"builtin-types": {
"name": "support.type.builtin.viper",
"match": "(?x)\n \\b(\n Any|Callable|ClassVar|Final|ForwardRef|Generic|Literal|NamedTuple|\n NewType|Optional|ParamSpec|Protocol|Tuple|Type|TypeAlias|TypeVar|\n TypeVarTuple|Union|Unpack|\n int|str|bytes|float|bool|list|dict|tuple|set|frozenset|object|type|\n complex|bytearray|memoryview|range|slice|None|True|False|Ellipsis\n )\\b"
},
"builtin-constants": {
"name": "support.constant.builtin.viper",
"match": "(?x)\n \\b(\n ArithmeticError|AssertionError|AttributeError|BaseException|\n BaseExceptionGroup|BlockingIOError|BrokenPipeError|BufferError|\n BytesWarning|ChildProcessError|ConnectionAbortedError|\n ConnectionError|ConnectionRefusedError|ConnectionResetError|\n DeprecationWarning|EOFError|EncodingWarning|EnvironmentError|\n Exception|ExceptionGroup|FileExistsError|FileNotFoundError|\n FloatingPointError|FutureWarning|GeneratorExit|IOError|ImportError|\n ImportWarning|IndentationError|IndexError|InterruptedError|\n IsADirectoryError|KeyError|KeyboardInterrupt|LookupError|MemoryError|\n ModuleNotFoundError|NameError|NotADirectoryError|\n NotImplementedWarning|OSError|OverflowError|\n PendingDeprecationWarning|PermissionError|ProcessLookupError|\n RecursionError|ReferenceError|ResourceWarning|RuntimeError|\n RuntimeWarning|StopAsyncIteration|StopIteration|SyntaxError|\n SyntaxWarning|SystemError|SystemExit|TabError|TimeoutError|TypeError|\n UnboundLocalError|UnicodeDecodeError|UnicodeEncodeError|UnicodeError|\n UnicodeTranslateError|UnicodeWarning|UserWarning|ValueError|Warning|\n WindowsError|ZeroDivisionError\n )\\b"
},
"magic-names": {
"name": "support.variable.magic.viper",
"match": "(?x)\n \\b(\n __all__|__bases__|__basicsize__|__builtins__|__class__|__dict__|\n __doc__|__file__|__flags__|__itemsize__|__members__|__module__|\n __mro__|__name__|__path__|__qualname__|__subclasses__|__version__|\n __abs__|__add__|__aenter__|__aexit__|__aiter__|__and__|__anext__|\n __await__|__bool__|__bytes__|__call__|__cmp__|__coerce__|__complex__|\n __contains__|__del__|__delattr__|__delete__|__delitem__|__delslice__|\n __dir__|__divmod__|__enter__|__eq__|__exit__|__float__|__floordiv__|\n __format__|__ge__|__get__|__getattr__|__getattribute__|__getitem__|\n __getnewargs__|__getslice__|__gt__|__hash__|__hex__|__iadd__|__iand__|\n __ifloordiv__|__ilshift__|__imatmul__|__imod__|__imul__|__index__|\n __init__|__init_subclass__|__int__|__invert__|__ior__|__ipow__|\n __irshift__|__isub__|__iter__|__itruediv__|__ixor__|__le__|__len__|\n __length_hint__|__lshift__|__lt__|__matmul__|__missing__|__mod__|\n __mro_entries__|__mul__|__ne__|__neg__|__new__|__next__|__nonzero__|\n __oct__|__or__|__pos__|__pow__|__radd__|__rand__|__rdivmod__|__repr__|\n __reversed__|__rfloordiv__|__rlshift__|__rmatmul__|__rmod__|__rmul__|\n __ror__|__round__|__rpow__|__rrshift__|__rshift__|__rsub__|\n __rtruediv__|__rxor__|__set__|__setattr__|__setitem__|__setslice__|\n __sizeof__|__str__|__sub__|__subclasshook__|__truediv__|__trunc__|\n __xor__\n )\\b"
},
"language-variable": {
"name": "variable.language.viper",
"match": "\\b(self|cls)\\b"
},
"variable": {
"name": "variable.other.viper",
"match": "\\b[A-Za-z_][\\w]*\\b"
},
"import-statement": {
"patterns": [
{
"name": "meta.import.viper",
"match": "(?x)\n ^[ \\t]*\n (from)\\s+\n ([A-Za-z_][\\w]*(?:\\.[A-Za-z_][\\w]*)*)\n \\s+(import)\\b",
"captures": {
"1": {"name": "keyword.control.import.viper"},
"2": {"name": "entity.name.namespace.viper"},
"3": {"name": "keyword.control.import.viper"}
}
},
{
"name": "meta.import.viper",
"begin": "(?x)^[ \\t]*(import)\\b\\s*",
"beginCaptures": {
"1": {"name": "keyword.control.import.viper"}
},
"end": "(?=#|$)",
"patterns": [
{
"match": "\\b(as)\\b",
"name": "keyword.control.import.viper"
},
{
"match": "\\b([A-Za-z_][\\w]*(?:\\.[A-Za-z_][\\w]*)*)\\b",
"name": "entity.name.namespace.viper"
},
{
"match": ",",
"name": "punctuation.separator.import.viper"
}
]
}
]
},
"class-call": {
"name": "meta.class-call.viper",
"match": "\\b([A-Z][\\w]*)\\s*(?=\\()",
"captures": {
"1": {"name": "entity.name.type.class.viper"}
}
},
"module-access": {
"patterns": [
{
"name": "meta.module-access.viper",
"match": "(?x)\n \\b(?!self\\b|cls\\b)([A-Za-z_][\\w]*)\n (\\.)\n ([A-Za-z_][\\w]*)\n \\s*(?=\\()",
"captures": {
"1": {"name": "entity.name.namespace.viper"},
"2": {"name": "punctuation.separator.dot.viper"},
"3": {"name": "entity.name.function.viper"}
}
},
{
"name": "meta.module-access.viper",
"match": "(?x)\n \\b(?!self\\b|cls\\b)([A-Za-z_][\\w]*)\n (\\.)\n ([A-Za-z_][\\w]*)",
"captures": {
"1": {"name": "entity.name.namespace.viper"},
"2": {"name": "punctuation.separator.dot.viper"},
"3": {"name": "variable.other.property.viper"}
}
}
]
},
"type-name": {
"name": "entity.name.type.class.viper",
"match": "\\b[A-Z][\\w]*\\b"
},
"type-annotation-string-single": {
"comment": "Viper 字符串注解(前向引用):匹配 var: '...' 形式的类型注解字符串",
"begin": "([A-Za-z_][\\w]*)\\s*(:)\\s*(')",
"beginCaptures": {
"1": { "name": "variable.other.property.viper" },
"2": { "name": "keyword.operator.annotation.viper" },
"3": { "name": "punctuation.definition.string.begin.viper" }
},
"end": "(')",
"endCaptures": {
"1": { "name": "punctuation.definition.string.end.viper" }
},
"contentName": "meta.type-annotation.viper",
"patterns": [
{ "include": "#type-annotation-content" }
]
},
"type-annotation-string-double": {
"comment": "Viper 字符串注解(前向引用):匹配 var: \"...\" 形式的类型注解字符串",
"begin": "([A-Za-z_][\\w]*)\\s*(:)\\s*(\")",
"beginCaptures": {
"1": { "name": "variable.other.property.viper" },
"2": { "name": "keyword.operator.annotation.viper" },
"3": { "name": "punctuation.definition.string.begin.viper" }
},
"end": "(\")",
"endCaptures": {
"1": { "name": "punctuation.definition.string.end.viper" }
},
"contentName": "meta.type-annotation.viper",
"patterns": [
{ "include": "#type-annotation-content" }
]
},
"type-annotation-content": {
"comment": "字符串注解内部的类型表达式(类型名、| 组合、None、t.CPtr 等模块限定类型)",
"patterns": [
{
"name": "keyword.operator.bitwise.or.viper",
"match": "\\|"
},
{
"name": "variable.language.viper",
"match": "\\bNone\\b"
},
{
"include": "#builtin-types"
},
{
"comment": "模块限定类型(如 t.CPtr, t.CInt)",
"match": "(?x)\\b([A-Za-z_][\\w]*)(\\.)([A-Za-z_][\\w]*)\\b",
"captures": {
"1": { "name": "entity.name.namespace.viper" },
"2": { "name": "punctuation.accessor.viper" },
"3": { "name": "entity.name.type.class.viper" }
}
},
{
"name": "punctuation.definition.type-arguments.begin.viper",
"match": "\\["
},
{
"name": "punctuation.definition.type-arguments.end.viper",
"match": "\\]"
},
{
"name": "punctuation.separator.type-arguments.viper",
"match": ","
},
{
"name": "entity.name.type.class.viper",
"match": "\\b[A-Za-z_][\\w]*\\b"
}
]
},
"return-type-string-single": {
"comment": "Viper 返回类型字符串注解:匹配 -> '...' 形式",
"begin": "(->)\\s*(')",
"beginCaptures": {
"1": { "name": "keyword.operator.arrow.viper" },
"2": { "name": "punctuation.definition.string.begin.viper" }
},
"end": "(')",
"endCaptures": {
"1": { "name": "punctuation.definition.string.end.viper" }
},
"contentName": "meta.type-annotation.viper",
"patterns": [
{ "include": "#type-annotation-content" }
]
},
"return-type-string-double": {
"comment": "Viper 返回类型字符串注解:匹配 -> \"...\" 形式",
"begin": "(->)\\s*(\")",
"beginCaptures": {
"1": { "name": "keyword.operator.arrow.viper" },
"2": { "name": "punctuation.definition.string.begin.viper" }
},
"end": "(\")",
"endCaptures": {
"1": { "name": "punctuation.definition.string.end.viper" }
},
"contentName": "meta.type-annotation.viper",
"patterns": [
{ "include": "#type-annotation-content" }
]
},
"illegal": {
"name": "invalid.illegal.viper",
"match": "\\b\\d+[^\\w\\s]"
}
}
}