修复了跨模块 typedef 等问题
This commit is contained in:
1 parent
ebe3638ff5
commit
a5d1841126
32 files changed
+38618
-39112
No files matched your search
@@ -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(),
|
||||
|
||||
@@ -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
|
||||
@@ -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]"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user