chore(syntax): Test 仓 R1 + R12 迁移

R1:T | t.CPtr -> T*(40 文件 / 1121 处;含多级 **、强转位 (T*)(x)、下标内 list[AST*]);引号前向引用 'Rect' | t.CPtr 26 处按例外保留,T | t.CPtr | t.State 25 处因 T* 后不能接 | 保持原联合写法。

R12:i = 0 + while i < N: + 尾 i += 1 -> or i in range(N):(10 文件 / 42 处;含 <= -> range(EXPR + 1)、带注解初始化 i: int = 0、尾 i = i + 1)。余 20 处经守卫判定不可安全改写(复合条件 1、尾部非自增 8、体内重绑定/continue 5、while-else 2、循环后仍被读取 2、找不到初始化 2)。
This commit is contained in:
TermiNexus committed 2026-10-05 21:18:37 +08:00
1 parent f5da836fbb
commit aa5a7e7250
43 files changed
+851 -935

No files matched your search

+18 -18
View File
@@ -9,7 +9,7 @@ import testcheck
# 全局 MBuddy 指针
_mbuddy: memhub.MemBuddy | t.CPtr
_mbuddy: memhub.MemBuddy*
@t.CExport
@@ -28,48 +28,48 @@ def main() -> int:
# 构造模拟 argv: myprog --input test.txt -c 42 --verbose output.dat
argv_buf: bytes = _mbuddy.alloc(8 * 7) # 7 个指针
argv: str | t.CPtr = (str | t.CPtr)(argv_buf)
argv: str* = (str*)(argv_buf)
# argv[0] = "myprog"
s0: bytes = _mbuddy.alloc(16)
string.strcpy(s0, "myprog")
argv0: str | t.CPtr = (str | t.CPtr)(uint64(argv))
argv0: str* = (str*)(uint64(argv))
argv0[0] = s0
# argv[1] = "--input"
s1: bytes = _mbuddy.alloc(16)
string.strcpy(s1, "--input")
argv1: str | t.CPtr = (str | t.CPtr)(uint64(argv) + 8)
argv1: str* = (str*)(uint64(argv) + 8)
argv1[0] = s1
# argv[2] = "test.txt"
s2: bytes = _mbuddy.alloc(16)
string.strcpy(s2, "test.txt")
argv2: str | t.CPtr = (str | t.CPtr)(uint64(argv) + 16)
argv2: str* = (str*)(uint64(argv) + 16)
argv2[0] = s2
# argv[3] = "-c"
s3: bytes = _mbuddy.alloc(8)
string.strcpy(s3, "-c")
argv3: str | t.CPtr = (str | t.CPtr)(uint64(argv) + 24)
argv3: str* = (str*)(uint64(argv) + 24)
argv3[0] = s3
# argv[4] = "42"
s4: bytes = _mbuddy.alloc(8)
string.strcpy(s4, "42")
argv4: str | t.CPtr = (str | t.CPtr)(uint64(argv) + 32)
argv4: str* = (str*)(uint64(argv) + 32)
argv4[0] = s4
# argv[5] = "--verbose"
s5: bytes = _mbuddy.alloc(16)
string.strcpy(s5, "--verbose")
argv5: str | t.CPtr = (str | t.CPtr)(uint64(argv) + 40)
argv5: str* = (str*)(uint64(argv) + 40)
argv5[0] = s5
# argv[6] = "output.dat"
s6: bytes = _mbuddy.alloc(16)
string.strcpy(s6, "output.dat")
argv6: str | t.CPtr = (str | t.CPtr)(uint64(argv) + 48)
argv6: str* = (str*)(uint64(argv) + 48)
argv6[0] = s6
argc: INT = 7
@@ -105,21 +105,21 @@ def main() -> int:
testcheck.section("Test 2: --name=value 语法")
argv2_buf: bytes = _mbuddy.alloc(8 * 3)
argv2: str | t.CPtr = (str | t.CPtr)(argv2_buf)
argv2: str* = (str*)(argv2_buf)
a0: bytes = _mbuddy.alloc(16)
string.strcpy(a0, "myprog")
a0_ptr: str | t.CPtr = (str | t.CPtr)(uint64(argv2))
a0_ptr: str* = (str*)(uint64(argv2))
a0_ptr[0] = a0
a1: bytes = _mbuddy.alloc(32)
string.strcpy(a1, "--input=hello.txt")
a1_ptr: str | t.CPtr = (str | t.CPtr)(uint64(argv2) + 8)
a1_ptr: str* = (str*)(uint64(argv2) + 8)
a1_ptr[0] = a1
a2: bytes = _mbuddy.alloc(16)
string.strcpy(a2, "output2.dat")
a2_ptr: str | t.CPtr = (str | t.CPtr)(uint64(argv2) + 16)
a2_ptr: str* = (str*)(uint64(argv2) + 16)
a2_ptr[0] = a2
args2 = parser.parse_args(3, argv2)
if args2 is not None:
@@ -140,26 +140,26 @@ def main() -> int:
testcheck.section("Test 3: COUNT 计数动作")
argv3_buf: bytes = _mbuddy.alloc(8 * 4)
argv3_arr: str | t.CPtr = (str | t.CPtr)(argv3_buf)
argv3_arr: str* = (str*)(argv3_buf)
b0: bytes = _mbuddy.alloc(8)
string.strcpy(b0, "myprog")
b0_ptr: str | t.CPtr = (str | t.CPtr)(uint64(argv3_arr))
b0_ptr: str* = (str*)(uint64(argv3_arr))
b0_ptr[0] = b0
b1: bytes = _mbuddy.alloc(8)
string.strcpy(b1, "-v")
b1_ptr: str | t.CPtr = (str | t.CPtr)(uint64(argv3_arr) + 8)
b1_ptr: str* = (str*)(uint64(argv3_arr) + 8)
b1_ptr[0] = b1
b2: bytes = _mbuddy.alloc(8)
string.strcpy(b2, "-v")
b2_ptr: str | t.CPtr = (str | t.CPtr)(uint64(argv3_arr) + 16)
b2_ptr: str* = (str*)(uint64(argv3_arr) + 16)
b2_ptr[0] = b2
b3: bytes = _mbuddy.alloc(16)
string.strcpy(b3, "output3.dat")
b3_ptr: str | t.CPtr = (str | t.CPtr)(uint64(argv3_arr) + 24)
b3_ptr: str* = (str*)(uint64(argv3_arr) + 24)
b3_ptr[0] = b3
parser2 = argparse.ArgumentParser("myprog", "Count test", pool=_mbuddy)
+25 -33
View File
@@ -18,18 +18,16 @@ define POOL_SIZE = 524288
define DUMP_SIZE = 262144
def classify_list(lst: list[ast.AST | t.CPtr] | t.CPtr, depth: int):
def classify_list(lst: list[ast.AST*]*, depth: int):
"""递归遍历 list[AST | t.CPtr] 容器,逐元素分类(orelse/args/comparators 等)"""
if lst is None:
return
n: sizet = lst.__len__()
i: sizet = 0
while i < n:
for i in range(n):
classify_print(lst.get(i), depth + 1)
i += 1
def classify_print(node: ast.AST | t.CPtr, depth: int):
def classify_print(node: ast.AST*, depth: int):
"""递归遍历 parse 树,用 isinstance 运行时判定每个节点的类别并打印。
依赖 TPV isinstance 的 vtable 子类集合比较:
@@ -40,10 +38,8 @@ def classify_print(node: ast.AST | t.CPtr, depth: int):
"""
if node is None:
return
sp: int = 0
while sp < depth:
for sp in range(depth):
printf(" ")
sp += 1
if isinstance(node, ast.Stmt) != 0:
printf("STMT %s\n", node.type_name())
elif isinstance(node, ast.ExprNode) != 0:
@@ -55,43 +51,43 @@ def classify_print(node: ast.AST | t.CPtr, depth: int):
# 直接访问 node.value 会在 AST 基类字段表 fast-fail(按需过滤原则)。
k: int = node.kind()
if k == ast.ASTKind.Assign:
asg: ast.Assign | t.CPtr = (ast.Assign | t.CPtr)(node)
asg: ast.Assign* = (ast.Assign*)(node)
classify_print(asg.value, depth + 1)
elif k == ast.ASTKind.If:
ifn: ast.If | t.CPtr = (ast.If | t.CPtr)(node)
ifn: ast.If* = (ast.If*)(node)
classify_print(ifn.test, depth + 1)
classify_list(ifn.orelse, depth + 1)
elif k == ast.ASTKind.While:
whl: ast.While | t.CPtr = (ast.While | t.CPtr)(node)
whl: ast.While* = (ast.While*)(node)
classify_print(whl.test, depth + 1)
classify_list(whl.orelse, depth + 1)
elif k == ast.ASTKind.For:
for_nd: ast.For | t.CPtr = (ast.For | t.CPtr)(node)
for_nd: ast.For* = (ast.For*)(node)
classify_print(for_nd.iter, depth + 1)
classify_print(for_nd.target, depth + 1)
classify_list(for_nd.orelse, depth + 1)
elif k == ast.ASTKind.Return:
ret_nd: ast.Return | t.CPtr = (ast.Return | t.CPtr)(node)
ret_nd: ast.Return* = (ast.Return*)(node)
classify_print(ret_nd.value, depth + 1)
elif k == ast.ASTKind.Expr:
expr_nd: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(node)
expr_nd: ast.Expr* = (ast.Expr*)(node)
classify_print(expr_nd.value, depth + 1)
elif k == ast.ASTKind.BinOp:
bin_nd: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
bin_nd: ast.BinOp* = (ast.BinOp*)(node)
classify_print(bin_nd.left, depth + 1)
classify_print(bin_nd.right, depth + 1)
elif k == ast.ASTKind.UnaryOp:
una_nd: ast.UnaryOp | t.CPtr = (ast.UnaryOp | t.CPtr)(node)
una_nd: ast.UnaryOp* = (ast.UnaryOp*)(node)
classify_print(una_nd.operand, depth + 1)
elif k == ast.ASTKind.Compare:
cmp_nd: ast.Compare | t.CPtr = (ast.Compare | t.CPtr)(node)
cmp_nd: ast.Compare* = (ast.Compare*)(node)
classify_print(cmp_nd.left, depth + 1)
classify_list(cmp_nd.comparators, depth + 1)
elif k == ast.ASTKind.BoolOp:
bool_nd: ast.BoolOp | t.CPtr = (ast.BoolOp | t.CPtr)(node)
bool_nd: ast.BoolOp* = (ast.BoolOp*)(node)
classify_list(bool_nd.values, depth + 1)
elif k == ast.ASTKind.Call:
call_nd: ast.Call | t.CPtr = (ast.Call | t.CPtr)(node)
call_nd: ast.Call* = (ast.Call*)(node)
classify_print(call_nd.func, depth + 1)
classify_list(call_nd.args, depth + 1)
else:
@@ -99,10 +95,8 @@ def classify_print(node: ast.AST | t.CPtr, depth: int):
# children(语句 body 块)
if node.children is not None:
n: sizet = node.children.__len__()
i: sizet = 0
while i < n:
for i in range(n):
classify_print(node.children.get(i), depth + 1)
i += 1
def main() -> CInt | CExport:
@@ -116,7 +110,7 @@ def main() -> CInt | CExport:
if arena == None:
printf("FAIL: arena alloc failed\n")
return 1
mbuddy_obj: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, ARENA_SIZE)
mbuddy_obj: memhub.MemBuddy* = memhub.MemBuddy(arena, ARENA_SIZE)
if mbuddy_obj == None:
printf("FAIL: mbuddy init failed\n")
return 1
@@ -129,7 +123,7 @@ def main() -> CInt | CExport:
if pool_mem == None:
printf("FAIL: malloc for pool failed\n")
return 1
pool: memhub.MemPool | t.CPtr = memhub.MemPool(pool_mem, POOL_SIZE)
pool: memhub.MemPool* = memhub.MemPool(pool_mem, POOL_SIZE)
if pool == None:
printf("FAIL: memhub.MemPool init failed\n")
return 1
@@ -139,7 +133,7 @@ def main() -> CInt | CExport:
if dump_mem == None:
printf("FAIL: malloc for dump failed\n")
return 1
dump_buf: char | t.CPtr = char(dump_mem, t.CPtr)
dump_buf: char* = char(dump_mem, t.CPtr)
# 综合测试源码:覆盖 CPython 主要语法
src: str = """x = 1
@@ -186,7 +180,7 @@ class Point:
stdlib.free(pool_mem)
stdlib.free(dump_mem)
return 1
tree: ast.AST | t.CPtr = ast.parse_tokens(pool, tokens_dbg)
tree: ast.AST* = ast.parse_tokens(pool, tokens_dbg)
if tree == None:
printf("FAIL: parse returned None\n")
stdlib.free(pool_mem)
@@ -216,18 +210,16 @@ class Point:
# 断言 2: 顶层 body 每条语句均为 Stmt
top_ok: int = 1
top_n: sizet = tree.children.__len__()
i2: sizet = 0
while i2 < top_n:
top_node: ast.AST | t.CPtr = tree.children.get(i2)
for i2 in range(top_n):
top_node: ast.AST* = tree.children.get(i2)
if isinstance(top_node, ast.Stmt) == 0:
top_ok = 0
printf("FAIL: top-level node not Stmt: %s\n", top_node.type_name())
i2 += 1
if top_ok != 0:
printf("PASS: all %lld top-level nodes are Stmt\n", top_n)
# 断言 3: Assign 是 Stmt 且不是 ExprNode
first_assign: ast.Assign | t.CPtr = (ast.Assign | t.CPtr)(tree.children.get(0))
first_assign: ast.Assign* = (ast.Assign*)(tree.children.get(0))
if isinstance(first_assign, ast.Stmt) != 0 and isinstance(first_assign, ast.ExprNode) == 0:
printf("PASS: Assign is Stmt, not ExprNode\n")
else:
@@ -242,9 +234,9 @@ class Point:
# 断言 5: 表达式语句 Expr(如 print(x))属于 Stmt(Statement 语义)
if top_n >= 15:
if_node: ast.If | t.CPtr = (ast.If | t.CPtr)(tree.children.get(14))
if_node: ast.If* = (ast.If*)(tree.children.get(14))
if if_node.children is not None and if_node.children.__len__() > 0:
expr_stmt: ast.Expr | t.CPtr = (ast.Expr | t.CPtr)(if_node.children.get(0))
expr_stmt: ast.Expr* = (ast.Expr*)(if_node.children.get(0))
if isinstance(expr_stmt, ast.Stmt) != 0 and isinstance(expr_stmt, ast.ExprNode) == 0:
printf("PASS: Expr(stmt) is Stmt, not ExprNode (%s)\n", expr_stmt.type_name())
else:
+2 -4
View File
@@ -13,7 +13,7 @@ import w32.win32base
# 线程函数: 在共享 MBuddy 上执行 alloc/free (测试 spinlock 线程安全)
def _thread_alloc_free(param: t.CPtr) -> uint32:
bd: memhub.MemBuddy | t.CPtr = (memhub.MemBuddy | t.CPtr)(param)
bd: memhub.MemBuddy* = (memhub.MemBuddy*)(param)
i: CInt
for i in range(100):
p: bytes = bd.alloc(32)
@@ -258,11 +258,9 @@ def mbuddy_main() -> CInt:
bd6.free(retry)
# 释放所有块
idx: CInt = 1
while idx < alloc_count:
for idx in range(1, alloc_count):
cur_p: bytes = t.CPtr(ptrs[idx])
bd6.free(cur_p)
idx += 1
# 全部释放后应能合并回初始分解块数 (6)
testcheck.check(bd6.free_count() == 6,
+282 -282
View File
@@ -12,11 +12,11 @@ class PyObject:
# ============================================================
# 引用计数
# ============================================================
extern def Py_INCREF(op: PyObject | t.CPtr)
extern def Py_DECREF(op: PyObject | t.CPtr)
extern def Py_XINCREF(op: PyObject | t.CPtr)
extern def Py_XDECREF(op: PyObject | t.CPtr)
extern def Py_DecRef(op: PyObject | t.CPtr)
extern def Py_INCREF(op: PyObject*)
extern def Py_DECREF(op: PyObject*)
extern def Py_XINCREF(op: PyObject*)
extern def Py_XDECREF(op: PyObject*)
extern def Py_DecRef(op: PyObject*)
# ============================================================
@@ -98,11 +98,11 @@ class PyConfig:
platlibdir: const str
stdio_filename: const str
extern def PyConfig_InitPythonConfig(config: PyConfig | t.CPtr)
extern def PyConfig_InitIsolatedConfig(config: PyConfig | t.CPtr)
extern def PyConfig_Clear(config: PyConfig | t.CPtr)
extern def PyConfig_Read(config: PyConfig | t.CPtr) -> PySTATUS
extern def Py_InitializeFromConfig(config: PyConfig | t.CPtr) -> PySTATUS
extern def PyConfig_InitPythonConfig(config: PyConfig*)
extern def PyConfig_InitIsolatedConfig(config: PyConfig*)
extern def PyConfig_Clear(config: PyConfig*)
extern def PyConfig_Read(config: PyConfig*) -> PySTATUS
extern def Py_InitializeFromConfig(config: PyConfig*) -> PySTATUS
extern def Py_DecodeLocale(s: const str) -> str
extern def PyStatus_Exception(status: PySTATUS) -> int
@@ -110,61 +110,61 @@ extern def PyStatus_Exception(status: PySTATUS) -> int
# ============================================================
# 整数操作 (PyLong)
# ============================================================
extern def PyLong_FromLong(v: int) -> PyObject | t.CPtr
extern def PyLong_FromUnsignedLong(v: t.CUnsignedLong) -> PyObject | t.CPtr
extern def PyLong_FromLongLong(v: t.CLong) -> PyObject | t.CPtr
extern def PyLong_FromUnsignedLongLong(v: t.CUnsignedLong) -> PyObject | t.CPtr
extern def PyLong_FromSsize_t(v: t.CPtrDiffT) -> PyObject | t.CPtr
extern def PyLong_FromSize_t(v: sizet) -> PyObject | t.CPtr
extern def PyLong_FromDouble(v: double) -> PyObject | t.CPtr
extern def PyLong_AsLong(obj: PyObject | t.CPtr) -> int
extern def PyLong_AsUnsignedLong(obj: PyObject | t.CPtr) -> t.CUnsignedLong
extern def PyLong_AsLongLong(obj: PyObject | t.CPtr) -> t.CLong
extern def PyLong_AsUnsignedLongLong(obj: PyObject | t.CPtr) -> t.CUnsignedLong
extern def PyLong_AsDouble(obj: PyObject | t.CPtr) -> double
extern def PyLong_AsSsize_t(obj: PyObject | t.CPtr) -> t.CPtrDiffT
extern def PyLong_AsSize_t(obj: PyObject | t.CPtr) -> sizet
extern def PyLong_FromLong(v: int) -> PyObject*
extern def PyLong_FromUnsignedLong(v: t.CUnsignedLong) -> PyObject*
extern def PyLong_FromLongLong(v: t.CLong) -> PyObject*
extern def PyLong_FromUnsignedLongLong(v: t.CUnsignedLong) -> PyObject*
extern def PyLong_FromSsize_t(v: t.CPtrDiffT) -> PyObject*
extern def PyLong_FromSize_t(v: sizet) -> PyObject*
extern def PyLong_FromDouble(v: double) -> PyObject*
extern def PyLong_AsLong(obj: PyObject*) -> int
extern def PyLong_AsUnsignedLong(obj: PyObject*) -> t.CUnsignedLong
extern def PyLong_AsLongLong(obj: PyObject*) -> t.CLong
extern def PyLong_AsUnsignedLongLong(obj: PyObject*) -> t.CUnsignedLong
extern def PyLong_AsDouble(obj: PyObject*) -> double
extern def PyLong_AsSsize_t(obj: PyObject*) -> t.CPtrDiffT
extern def PyLong_AsSize_t(obj: PyObject*) -> sizet
# ============================================================
# 浮点数操作 (PyFloat)
# ============================================================
extern def PyFloat_FromDouble(v: double) -> PyObject | t.CPtr
extern def PyFloat_AsDouble(obj: PyObject | t.CPtr) -> double
extern def PyFloat_FromString(s: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyFloat_FromDouble(v: double) -> PyObject*
extern def PyFloat_AsDouble(obj: PyObject*) -> double
extern def PyFloat_FromString(s: PyObject*) -> PyObject*
# ============================================================
# 字符串操作 (PyUnicode / PyBytes)
# ============================================================
extern def PyUnicode_FromString(u: const str) -> PyObject | t.CPtr
extern def PyUnicode_FromStringAndSize(u: const str, size: sizet) -> PyObject | t.CPtr
extern def PyUnicode_FromFormat(fmt: const str) -> PyObject | t.CPtr
extern def PyUnicode_AsUTF8(obj: PyObject | t.CPtr) -> str
extern def PyUnicode_AsUTF8AndSize(obj: PyObject | t.CPtr, size: t.CPtrDiffT | t.CPtr) -> str
extern def PyUnicode_AsWideChar(obj: PyObject | t.CPtr, wbuf: t.CPtr, bufsize: sizet) -> sizet
extern def PyUnicode_GetLength(obj: PyObject | t.CPtr) -> t.CPtrDiffT
extern def PyUnicode_ReadChar(obj: PyObject | t.CPtr, idx: sizet) -> uint32
extern def PyUnicode_WriteChar(obj: PyObject | t.CPtr, idx: sizet, ch: uint32) -> int
extern def PyUnicode_Compare(l: PyObject | t.CPtr, r: PyObject | t.CPtr) -> int
extern def PyUnicode_Concat(l: PyObject | t.CPtr, r: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyUnicode_Contains(container: PyObject | t.CPtr, element: PyObject | t.CPtr) -> int
extern def PyUnicode_Format(fmt: PyObject | t.CPtr, args: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyUnicode_InternInPlace(s: PyObject | t.CPtr | t.CPtr): pass
extern def PyUnicode_InternFromString(u: const str) -> PyObject | t.CPtr
extern def PyUnicode_FromString(u: const str) -> PyObject*
extern def PyUnicode_FromStringAndSize(u: const str, size: sizet) -> PyObject*
extern def PyUnicode_FromFormat(fmt: const str) -> PyObject*
extern def PyUnicode_AsUTF8(obj: PyObject*) -> str
extern def PyUnicode_AsUTF8AndSize(obj: PyObject*, size: t.CPtrDiffT*) -> str
extern def PyUnicode_AsWideChar(obj: PyObject*, wbuf: t.CPtr, bufsize: sizet) -> sizet
extern def PyUnicode_GetLength(obj: PyObject*) -> t.CPtrDiffT
extern def PyUnicode_ReadChar(obj: PyObject*, idx: sizet) -> uint32
extern def PyUnicode_WriteChar(obj: PyObject*, idx: sizet, ch: uint32) -> int
extern def PyUnicode_Compare(l: PyObject*, r: PyObject*) -> int
extern def PyUnicode_Concat(l: PyObject*, r: PyObject*) -> PyObject*
extern def PyUnicode_Contains(container: PyObject*, element: PyObject*) -> int
extern def PyUnicode_Format(fmt: PyObject*, args: PyObject*) -> PyObject*
extern def PyUnicode_InternInPlace(s: PyObject**): pass
extern def PyUnicode_InternFromString(u: const str) -> PyObject*
extern def PyBytes_FromString(v: const str) -> PyObject | t.CPtr
extern def PyBytes_FromStringAndSize(v: const str, size: sizet) -> PyObject | t.CPtr
extern def PyBytes_AsString(obj: PyObject | t.CPtr) -> str
extern def PyBytes_Size(obj: PyObject | t.CPtr) -> sizet
extern def PyBytes_FromObject(o: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyBytes_FromFormat(fmt: const str) -> PyObject | t.CPtr
extern def PyBytes_FromString(v: const str) -> PyObject*
extern def PyBytes_FromStringAndSize(v: const str, size: sizet) -> PyObject*
extern def PyBytes_AsString(obj: PyObject*) -> str
extern def PyBytes_Size(obj: PyObject*) -> sizet
extern def PyBytes_FromObject(o: PyObject*) -> PyObject*
extern def PyBytes_FromFormat(fmt: const str) -> PyObject*
# ============================================================
# 布尔 / None
# ============================================================
extern def PyBool_FromLong(v: t.CLong) -> PyObject | t.CPtr
extern def PyBool_FromLong(v: t.CLong) -> PyObject*
Py_True: PyObject | t.CPtr | t.State
Py_False: PyObject | t.CPtr | t.State
@@ -174,84 +174,84 @@ Py_None: PyObject | t.CPtr | t.State
# ============================================================
# 列表操作 (PyList)
# ============================================================
extern def PyList_New(len: sizet) -> PyObject | t.CPtr
extern def PyList_Size(lst: PyObject | t.CPtr) -> sizet
extern def PyList_GetItem(lst: PyObject | t.CPtr, idx: sizet) -> PyObject | t.CPtr
extern def PyList_SetItem(lst: PyObject | t.CPtr, idx: sizet, item: PyObject | t.CPtr) -> int
extern def PyList_Insert(lst: PyObject | t.CPtr, idx: sizet, item: PyObject | t.CPtr) -> int
extern def PyList_Append(lst: PyObject | t.CPtr, item: PyObject | t.CPtr) -> int
extern def PyList_GetSlice(lst: PyObject | t.CPtr, lo: sizet, hi: sizet) -> PyObject | t.CPtr
extern def PyList_SetSlice(lst: PyObject | t.CPtr, lo: sizet, hi: sizet, items: PyObject | t.CPtr) -> int
extern def PyList_Sort(lst: PyObject | t.CPtr) -> int
extern def PyList_Reverse(lst: PyObject | t.CPtr) -> int
extern def PyList_AsTuple(lst: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyList_New(len: sizet) -> PyObject*
extern def PyList_Size(lst: PyObject*) -> sizet
extern def PyList_GetItem(lst: PyObject*, idx: sizet) -> PyObject*
extern def PyList_SetItem(lst: PyObject*, idx: sizet, item: PyObject*) -> int
extern def PyList_Insert(lst: PyObject*, idx: sizet, item: PyObject*) -> int
extern def PyList_Append(lst: PyObject*, item: PyObject*) -> int
extern def PyList_GetSlice(lst: PyObject*, lo: sizet, hi: sizet) -> PyObject*
extern def PyList_SetSlice(lst: PyObject*, lo: sizet, hi: sizet, items: PyObject*) -> int
extern def PyList_Sort(lst: PyObject*) -> int
extern def PyList_Reverse(lst: PyObject*) -> int
extern def PyList_AsTuple(lst: PyObject*) -> PyObject*
# ============================================================
# 元组操作 (PyTuple)
# ============================================================
extern def PyTuple_New(len: sizet) -> PyObject | t.CPtr
extern def PyTuple_Size(tup: PyObject | t.CPtr) -> sizet
extern def PyTuple_GetItem(tup: PyObject | t.CPtr, idx: sizet) -> PyObject | t.CPtr
extern def PyTuple_SetItem(tup: PyObject | t.CPtr, idx: sizet, item: PyObject | t.CPtr) -> int
extern def PyTuple_GetSlice(tup: PyObject | t.CPtr, lo: sizet, hi: sizet) -> PyObject | t.CPtr
extern def PyTuple_Pack(n: sizet) -> PyObject | t.CPtr
extern def PyTuple_New(len: sizet) -> PyObject*
extern def PyTuple_Size(tup: PyObject*) -> sizet
extern def PyTuple_GetItem(tup: PyObject*, idx: sizet) -> PyObject*
extern def PyTuple_SetItem(tup: PyObject*, idx: sizet, item: PyObject*) -> int
extern def PyTuple_GetSlice(tup: PyObject*, lo: sizet, hi: sizet) -> PyObject*
extern def PyTuple_Pack(n: sizet) -> PyObject*
# ============================================================
# 字典操作 (PyDict)
# ============================================================
extern def PyDict_New() -> PyObject | t.CPtr
extern def PyDict_GetItem(d: PyObject | t.CPtr, key: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyDict_GetItemString(d: PyObject | t.CPtr, key: const str) -> PyObject | t.CPtr
extern def PyDict_SetItem(d: PyObject | t.CPtr, key: PyObject | t.CPtr, val: PyObject | t.CPtr) -> int
extern def PyDict_SetItemString(d: PyObject | t.CPtr, key: const str, val: PyObject | t.CPtr) -> int
extern def PyDict_DelItem(d: PyObject | t.CPtr, key: PyObject | t.CPtr) -> int
extern def PyDict_DelItemString(d: PyObject | t.CPtr, key: const str) -> int
extern def PyDict_Size(d: PyObject | t.CPtr) -> sizet
extern def PyDict_Keys(d: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyDict_Values(d: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyDict_Items(d: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyDict_Copy(d: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyDict_Clear(d: PyObject | t.CPtr): pass
extern def PyDict_Contains(d: PyObject | t.CPtr, key: PyObject | t.CPtr) -> int
extern def PyDict_Next(d: PyObject | t.CPtr, pos: t.CPtrDiffT | t.CPtr, key: PyObject | t.CPtr | t.CPtr, val: PyObject | t.CPtr | t.CPtr) -> int
extern def PyDict_Merge(d: PyObject | t.CPtr, other: PyObject | t.CPtr, override: int) -> int
extern def PyDict_Update(d: PyObject | t.CPtr, other: PyObject | t.CPtr) -> int
extern def PyDict_New() -> PyObject*
extern def PyDict_GetItem(d: PyObject*, key: PyObject*) -> PyObject*
extern def PyDict_GetItemString(d: PyObject*, key: const str) -> PyObject*
extern def PyDict_SetItem(d: PyObject*, key: PyObject*, val: PyObject*) -> int
extern def PyDict_SetItemString(d: PyObject*, key: const str, val: PyObject*) -> int
extern def PyDict_DelItem(d: PyObject*, key: PyObject*) -> int
extern def PyDict_DelItemString(d: PyObject*, key: const str) -> int
extern def PyDict_Size(d: PyObject*) -> sizet
extern def PyDict_Keys(d: PyObject*) -> PyObject*
extern def PyDict_Values(d: PyObject*) -> PyObject*
extern def PyDict_Items(d: PyObject*) -> PyObject*
extern def PyDict_Copy(d: PyObject*) -> PyObject*
extern def PyDict_Clear(d: PyObject*): pass
extern def PyDict_Contains(d: PyObject*, key: PyObject*) -> int
extern def PyDict_Next(d: PyObject*, pos: t.CPtrDiffT*, key: PyObject**, val: PyObject**) -> int
extern def PyDict_Merge(d: PyObject*, other: PyObject*, override: int) -> int
extern def PyDict_Update(d: PyObject*, other: PyObject*) -> int
# ============================================================
# 对象通用操作
# ============================================================
extern def PyObject_Str(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_Repr(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_Type(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_IsInstance(obj: PyObject | t.CPtr, cls: PyObject | t.CPtr) -> int
extern def PyObject_IsSubclass(obj: PyObject | t.CPtr, cls: PyObject | t.CPtr) -> int
extern def PyObject_HasAttr(obj: PyObject | t.CPtr, name: PyObject | t.CPtr) -> int
extern def PyObject_HasAttrString(obj: PyObject | t.CPtr, name: const str) -> int
extern def PyObject_GetAttr(obj: PyObject | t.CPtr, name: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_GetAttrString(obj: PyObject | t.CPtr, name: const str) -> PyObject | t.CPtr
extern def PyObject_SetAttr(obj: PyObject | t.CPtr, name: PyObject | t.CPtr, val: PyObject | t.CPtr) -> int
extern def PyObject_SetAttrString(obj: PyObject | t.CPtr, name: const str, val: PyObject | t.CPtr) -> int
extern def PyObject_DelAttr(obj: PyObject | t.CPtr, name: PyObject | t.CPtr) -> int
extern def PyObject_DelAttrString(obj: PyObject | t.CPtr, name: const str) -> int
extern def PyObject_Call(callable: PyObject | t.CPtr, args: PyObject | t.CPtr, kwargs: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_CallObject(callable: PyObject | t.CPtr, args: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_CallNoArgs(callable: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_CallOneArg(callable: PyObject | t.CPtr, arg: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_IsTrue(obj: PyObject | t.CPtr) -> int
extern def PyObject_Not(obj: PyObject | t.CPtr) -> int
extern def PyObject_RichCompare(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr, opid: int) -> PyObject | t.CPtr
extern def PyObject_RichCompareBool(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr, opid: int) -> int
extern def PyObject_Hash(obj: PyObject | t.CPtr) -> t.CLong
extern def PyObject_Length(obj: PyObject | t.CPtr) -> sizet
extern def PyObject_GetItem(obj: PyObject | t.CPtr, key: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_SetItem(obj: PyObject | t.CPtr, key: PyObject | t.CPtr, val: PyObject | t.CPtr) -> int
extern def PyObject_DelItem(obj: PyObject | t.CPtr, key: PyObject | t.CPtr) -> int
extern def PyObject_Dir(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_GetIter(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyIter_Next(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyObject_Str(obj: PyObject*) -> PyObject*
extern def PyObject_Repr(obj: PyObject*) -> PyObject*
extern def PyObject_Type(obj: PyObject*) -> PyObject*
extern def PyObject_IsInstance(obj: PyObject*, cls: PyObject*) -> int
extern def PyObject_IsSubclass(obj: PyObject*, cls: PyObject*) -> int
extern def PyObject_HasAttr(obj: PyObject*, name: PyObject*) -> int
extern def PyObject_HasAttrString(obj: PyObject*, name: const str) -> int
extern def PyObject_GetAttr(obj: PyObject*, name: PyObject*) -> PyObject*
extern def PyObject_GetAttrString(obj: PyObject*, name: const str) -> PyObject*
extern def PyObject_SetAttr(obj: PyObject*, name: PyObject*, val: PyObject*) -> int
extern def PyObject_SetAttrString(obj: PyObject*, name: const str, val: PyObject*) -> int
extern def PyObject_DelAttr(obj: PyObject*, name: PyObject*) -> int
extern def PyObject_DelAttrString(obj: PyObject*, name: const str) -> int
extern def PyObject_Call(callable: PyObject*, args: PyObject*, kwargs: PyObject*) -> PyObject*
extern def PyObject_CallObject(callable: PyObject*, args: PyObject*) -> PyObject*
extern def PyObject_CallNoArgs(callable: PyObject*) -> PyObject*
extern def PyObject_CallOneArg(callable: PyObject*, arg: PyObject*) -> PyObject*
extern def PyObject_IsTrue(obj: PyObject*) -> int
extern def PyObject_Not(obj: PyObject*) -> int
extern def PyObject_RichCompare(o1: PyObject*, o2: PyObject*, opid: int) -> PyObject*
extern def PyObject_RichCompareBool(o1: PyObject*, o2: PyObject*, opid: int) -> int
extern def PyObject_Hash(obj: PyObject*) -> t.CLong
extern def PyObject_Length(obj: PyObject*) -> sizet
extern def PyObject_GetItem(obj: PyObject*, key: PyObject*) -> PyObject*
extern def PyObject_SetItem(obj: PyObject*, key: PyObject*, val: PyObject*) -> int
extern def PyObject_DelItem(obj: PyObject*, key: PyObject*) -> int
extern def PyObject_Dir(obj: PyObject*) -> PyObject*
extern def PyObject_GetIter(obj: PyObject*) -> PyObject*
extern def PyIter_Next(obj: PyObject*) -> PyObject*
# ============================================================
@@ -268,13 +268,13 @@ Py_GE: int | t.State
# ============================================================
# 模块操作
# ============================================================
extern def PyImport_ImportModule(name: const str) -> PyObject | t.CPtr
extern def PyImport_Import(name: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyImport_ImportModuleLevelObject(name: PyObject | t.CPtr, globs: PyObject | t.CPtr, locs: PyObject | t.CPtr, fromlist: PyObject | t.CPtr, level: int) -> PyObject | t.CPtr
extern def PyImport_ReloadModule(mod: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyImport_AddModule(name: const str) -> PyObject | t.CPtr
extern def PyImport_GetModuleDict() -> PyObject | t.CPtr
extern def PyImport_ImportModuleEx(name: const str, globs: PyObject | t.CPtr, locs: PyObject | t.CPtr, fromlist: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyImport_ImportModule(name: const str) -> PyObject*
extern def PyImport_Import(name: PyObject*) -> PyObject*
extern def PyImport_ImportModuleLevelObject(name: PyObject*, globs: PyObject*, locs: PyObject*, fromlist: PyObject*, level: int) -> PyObject*
extern def PyImport_ReloadModule(mod: PyObject*) -> PyObject*
extern def PyImport_AddModule(name: const str) -> PyObject*
extern def PyImport_GetModuleDict() -> PyObject*
extern def PyImport_ImportModuleEx(name: const str, globs: PyObject*, locs: PyObject*, fromlist: PyObject*) -> PyObject*
# ============================================================
@@ -290,28 +290,28 @@ class PyModuleDef_Base:
ob_base: PyObject
m_init: t.CPtr
m_index: sizet
m_copy: PyObject | t.CPtr
m_copy: PyObject*
class PyModuleDef:
m_base: PyModuleDef_Base
m_name: const str
m_doc: const str
m_size: t.CPtrDiffT
m_methods: PyMethodDef | t.CPtr
m_methods: PyMethodDef*
m_slots: t.CPtr
m_traverse: t.CPtr
m_clear: t.CPtr
m_free: t.CPtr
extern def PyModule_Create(mod: PyModuleDef | t.CPtr) -> PyObject | t.CPtr
extern def PyModule_Create2(mod: PyModuleDef | t.CPtr, ver: int) -> PyObject | t.CPtr
extern def PyModule_GetName(mod: PyObject | t.CPtr) -> str
extern def PyModule_GetDict(mod: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyModule_GetFilenameObject(mod: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyModule_AddObject(mod: PyObject | t.CPtr, name: const str, val: PyObject | t.CPtr) -> int
extern def PyModule_AddObjectRef(mod: PyObject | t.CPtr, name: const str, val: PyObject | t.CPtr) -> int
extern def PyModule_AddIntConstant(mod: PyObject | t.CPtr, name: const str, val: t.CLong) -> int
extern def PyModule_AddStringConstant(mod: PyObject | t.CPtr, name: const str, val: const str) -> int
extern def PyModule_Create(mod: PyModuleDef*) -> PyObject*
extern def PyModule_Create2(mod: PyModuleDef*, ver: int) -> PyObject*
extern def PyModule_GetName(mod: PyObject*) -> str
extern def PyModule_GetDict(mod: PyObject*) -> PyObject*
extern def PyModule_GetFilenameObject(mod: PyObject*) -> PyObject*
extern def PyModule_AddObject(mod: PyObject*, name: const str, val: PyObject*) -> int
extern def PyModule_AddObjectRef(mod: PyObject*, name: const str, val: PyObject*) -> int
extern def PyModule_AddIntConstant(mod: PyObject*, name: const str, val: t.CLong) -> int
extern def PyModule_AddStringConstant(mod: PyObject*, name: const str, val: const str) -> int
# ============================================================
@@ -332,18 +332,18 @@ extern def PyEval_InitThreads(): pass
# ============================================================
# 错误处理
# ============================================================
extern def PyErr_Occurred() -> PyObject | t.CPtr
extern def PyErr_Occurred() -> PyObject*
extern def PyErr_Clear(): pass
extern def PyErr_Fetch(tp: PyObject | t.CPtr | t.CPtr, val: PyObject | t.CPtr | t.CPtr, tb: PyObject | t.CPtr | t.CPtr): pass
extern def PyErr_Restore(tp: PyObject | t.CPtr, val: PyObject | t.CPtr, tb: PyObject | t.CPtr): pass
extern def PyErr_NormalizeException(tp: PyObject | t.CPtr | t.CPtr, val: PyObject | t.CPtr | t.CPtr, tb: PyObject | t.CPtr | t.CPtr): pass
extern def PyErr_SetString(tp: PyObject | t.CPtr, msg: const str): pass
extern def PyErr_SetObject(tp: PyObject | t.CPtr, val: PyObject | t.CPtr): pass
extern def PyErr_Fetch(tp: PyObject**, val: PyObject**, tb: PyObject**): pass
extern def PyErr_Restore(tp: PyObject*, val: PyObject*, tb: PyObject*): pass
extern def PyErr_NormalizeException(tp: PyObject**, val: PyObject**, tb: PyObject**): pass
extern def PyErr_SetString(tp: PyObject*, msg: const str): pass
extern def PyErr_SetObject(tp: PyObject*, val: PyObject*): pass
extern def PyErr_BadArgument() -> t.CPtr | t.State: pass
extern def PyErr_NoMemory() -> t.CPtr | t.State: pass
extern def PyErr_Print(): pass
extern def PyErr_ExceptionMatches(exc: PyObject | t.CPtr) -> int | t.State: pass
extern def PyErr_GivenExceptionMatches(given: PyObject | t.CPtr, exc: PyObject | t.CPtr) -> int | t.State: pass
extern def PyErr_ExceptionMatches(exc: PyObject*) -> int | t.State: pass
extern def PyErr_GivenExceptionMatches(given: PyObject*, exc: PyObject*) -> int | t.State: pass
# ============================================================
@@ -376,22 +376,22 @@ PyExc_NotADirectoryError: PyObject | t.CPtr | t.State
# ============================================================
# 内置函数
# ============================================================
extern def Py_BuildValue(fmt: const str) -> PyObject | t.CPtr
extern def Py_VaBuildValue(fmt: const str, va: t.CPtr) -> PyObject | t.CPtr
extern def Py_BuildValue(fmt: const str) -> PyObject*
extern def Py_VaBuildValue(fmt: const str, va: t.CPtr) -> PyObject*
# ============================================================
# 类型检查
# ============================================================
extern def PyLong_Check(obj: PyObject | t.CPtr) -> int
extern def PyFloat_Check(obj: PyObject | t.CPtr) -> int
extern def PyUnicode_Check(obj: PyObject | t.CPtr) -> int
extern def PyBytes_Check(obj: PyObject | t.CPtr) -> int
extern def PyList_Check(obj: PyObject | t.CPtr) -> int
extern def PyTuple_Check(obj: PyObject | t.CPtr) -> int
extern def PyDict_Check(obj: PyObject | t.CPtr) -> int
extern def PyBool_Check(obj: PyObject | t.CPtr) -> int
extern def PyNone_Check(obj: PyObject | t.CPtr) -> int
extern def PyLong_Check(obj: PyObject*) -> int
extern def PyFloat_Check(obj: PyObject*) -> int
extern def PyUnicode_Check(obj: PyObject*) -> int
extern def PyBytes_Check(obj: PyObject*) -> int
extern def PyList_Check(obj: PyObject*) -> int
extern def PyTuple_Check(obj: PyObject*) -> int
extern def PyDict_Check(obj: PyObject*) -> int
extern def PyBool_Check(obj: PyObject*) -> int
extern def PyNone_Check(obj: PyObject*) -> int
# ============================================================
@@ -405,29 +405,29 @@ extern def PyObject_Malloc(size: sizet) -> t.CPtr
extern def PyObject_Realloc(ptr: t.CPtr, size: sizet) -> t.CPtr
extern def PyObject_Free(ptr: t.CPtr)
extern def PyObject_Calloc(nelem: sizet, elsize: sizet) -> t.CPtr
extern def PyObject_Init(obj: PyObject | t.CPtr, tp: t.CPtr) -> PyObject | t.CPtr
extern def PyObject_InitVar(obj: PyObject | t.CPtr, tp: t.CPtr, size: sizet) -> PyObject | t.CPtr
extern def PyObject_Init(obj: PyObject*, tp: t.CPtr) -> PyObject*
extern def PyObject_InitVar(obj: PyObject*, tp: t.CPtr, size: sizet) -> PyObject*
# ============================================================
# 文件操作
# ============================================================
extern def PyFile_FromString(filename: const str, mode: const str) -> PyObject | t.CPtr
extern def PyFile_AsFile(file: PyObject | t.CPtr) -> t.CPtr
extern def PyFile_WriteObject(obj: PyObject | t.CPtr, file: PyObject | t.CPtr, flags: int) -> int
extern def PyFile_WriteString(s: const str, file: PyObject | t.CPtr) -> int
extern def PyFile_FromString(filename: const str, mode: const str) -> PyObject*
extern def PyFile_AsFile(file: PyObject*) -> t.CPtr
extern def PyFile_WriteObject(obj: PyObject*, file: PyObject*, flags: int) -> int
extern def PyFile_WriteString(s: const str, file: PyObject*) -> int
# ============================================================
# 编译/执行
# ============================================================
extern def Py_CompileString(s: const str, filename: const str, start: int) -> PyObject | t.CPtr
extern def PyEval_EvalCode(code: PyObject | t.CPtr, globs: PyObject | t.CPtr, locs: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyEval_EvalCodeEx(code: PyObject | t.CPtr, globs: PyObject | t.CPtr, locs: PyObject | t.CPtr, args: PyObject | t.CPtr | t.CPtr, argc: int, kws: PyObject | t.CPtr | t.CPtr, kwc: int, defs: PyObject | t.CPtr | t.CPtr, defc: int, kwdefs: PyObject | t.CPtr, closure: PyObject | t.CPtr) -> PyObject | t.CPtr: pass
extern def PyEval_EvalFrame(frame: t.CPtr) -> PyObject | t.CPtr: pass
extern def PyEval_CallObject(callable: PyObject | t.CPtr, args: PyObject | t.CPtr) -> PyObject | t.CPtr: pass
extern def PyEval_CallFunction(callable: PyObject | t.CPtr, fmt: const str) -> PyObject | t.CPtr: pass
extern def PyEval_CallMethod(obj: PyObject | t.CPtr, method: const str, fmt: const str) -> PyObject | t.CPtr: pass
extern def Py_CompileString(s: const str, filename: const str, start: int) -> PyObject*
extern def PyEval_EvalCode(code: PyObject*, globs: PyObject*, locs: PyObject*) -> PyObject*
extern def PyEval_EvalCodeEx(code: PyObject*, globs: PyObject*, locs: PyObject*, args: PyObject**, argc: int, kws: PyObject**, kwc: int, defs: PyObject**, defc: int, kwdefs: PyObject*, closure: PyObject*) -> PyObject*: pass
extern def PyEval_EvalFrame(frame: t.CPtr) -> PyObject*: pass
extern def PyEval_CallObject(callable: PyObject*, args: PyObject*) -> PyObject*: pass
extern def PyEval_CallFunction(callable: PyObject*, fmt: const str) -> PyObject*: pass
extern def PyEval_CallMethod(obj: PyObject*, method: const str, fmt: const str) -> PyObject*: pass
# ============================================================
@@ -436,8 +436,8 @@ extern def PyEval_CallMethod(obj: PyObject | t.CPtr, method: const str, fmt: con
extern def PyRun_SimpleString(cmd: const str) -> int
extern def PyRun_SimpleFile(fp: t.CPtr, filename: const str) -> int
extern def PyRun_AnyFile(fp: t.CPtr, filename: const str) -> int
extern def PyRun_String(s: const str, start: int, globs: PyObject | t.CPtr, locs: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyRun_File(fp: t.CPtr, filename: const str, start: int, globs: PyObject | t.CPtr, locs: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyRun_String(s: const str, start: int, globs: PyObject*, locs: PyObject*) -> PyObject*
extern def PyRun_File(fp: t.CPtr, filename: const str, start: int, globs: PyObject*, locs: PyObject*) -> PyObject*
Py_single_input: int | t.State
Py_file_input: int | t.State
@@ -447,83 +447,83 @@ Py_eval_input: int | t.State
# ============================================================
# Capsule
# ============================================================
extern def PyCapsule_New(ptr: t.CPtr, name: const str, dtor: t.CPtr) -> PyObject | t.CPtr
extern def PyCapsule_GetPointer(cap: PyObject | t.CPtr, name: const str) -> t.CPtr
extern def PyCapsule_GetName(cap: PyObject | t.CPtr) -> str
extern def PyCapsule_IsValid(cap: PyObject | t.CPtr, name: const str) -> int
extern def PyCapsule_SetPointer(cap: PyObject | t.CPtr, ptr: t.CPtr) -> int
extern def PyCapsule_SetName(cap: PyObject | t.CPtr, name: const str) -> int
extern def PyCapsule_SetDestructor(cap: PyObject | t.CPtr, dtor: t.CPtr) -> int
extern def PyCapsule_New(ptr: t.CPtr, name: const str, dtor: t.CPtr) -> PyObject*
extern def PyCapsule_GetPointer(cap: PyObject*, name: const str) -> t.CPtr
extern def PyCapsule_GetName(cap: PyObject*) -> str
extern def PyCapsule_IsValid(cap: PyObject*, name: const str) -> int
extern def PyCapsule_SetPointer(cap: PyObject*, ptr: t.CPtr) -> int
extern def PyCapsule_SetName(cap: PyObject*, name: const str) -> int
extern def PyCapsule_SetDestructor(cap: PyObject*, dtor: t.CPtr) -> int
# ============================================================
# 序列操作
# ============================================================
extern def PySequence_Check(obj: PyObject | t.CPtr) -> int
extern def PySequence_Size(obj: PyObject | t.CPtr) -> sizet
extern def PySequence_Length(obj: PyObject | t.CPtr) -> sizet
extern def PySequence_Concat(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PySequence_Repeat(obj: PyObject | t.CPtr, count: sizet) -> PyObject | t.CPtr
extern def PySequence_GetItem(obj: PyObject | t.CPtr, idx: sizet) -> PyObject | t.CPtr
extern def PySequence_SetItem(obj: PyObject | t.CPtr, idx: sizet, val: PyObject | t.CPtr) -> int
extern def PySequence_DelItem(obj: PyObject | t.CPtr, idx: sizet) -> int
extern def PySequence_GetSlice(obj: PyObject | t.CPtr, start: sizet, end: sizet) -> PyObject | t.CPtr
extern def PySequence_SetSlice(obj: PyObject | t.CPtr, start: sizet, end: sizet, val: PyObject | t.CPtr) -> int
extern def PySequence_DelSlice(obj: PyObject | t.CPtr, start: sizet, end: sizet) -> int
extern def PySequence_Contains(obj: PyObject | t.CPtr, val: PyObject | t.CPtr) -> int
extern def PySequence_Index(obj: PyObject | t.CPtr, val: PyObject | t.CPtr) -> sizet
extern def PySequence_Count(obj: PyObject | t.CPtr, val: PyObject | t.CPtr) -> sizet
extern def PySequence_List(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PySequence_Tuple(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PySequence_Check(obj: PyObject*) -> int
extern def PySequence_Size(obj: PyObject*) -> sizet
extern def PySequence_Length(obj: PyObject*) -> sizet
extern def PySequence_Concat(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PySequence_Repeat(obj: PyObject*, count: sizet) -> PyObject*
extern def PySequence_GetItem(obj: PyObject*, idx: sizet) -> PyObject*
extern def PySequence_SetItem(obj: PyObject*, idx: sizet, val: PyObject*) -> int
extern def PySequence_DelItem(obj: PyObject*, idx: sizet) -> int
extern def PySequence_GetSlice(obj: PyObject*, start: sizet, end: sizet) -> PyObject*
extern def PySequence_SetSlice(obj: PyObject*, start: sizet, end: sizet, val: PyObject*) -> int
extern def PySequence_DelSlice(obj: PyObject*, start: sizet, end: sizet) -> int
extern def PySequence_Contains(obj: PyObject*, val: PyObject*) -> int
extern def PySequence_Index(obj: PyObject*, val: PyObject*) -> sizet
extern def PySequence_Count(obj: PyObject*, val: PyObject*) -> sizet
extern def PySequence_List(obj: PyObject*) -> PyObject*
extern def PySequence_Tuple(obj: PyObject*) -> PyObject*
# ============================================================
# 映射操作
# ============================================================
extern def PyMapping_Check(obj: PyObject | t.CPtr) -> int
extern def PyMapping_Size(obj: PyObject | t.CPtr) -> sizet
extern def PyMapping_Length(obj: PyObject | t.CPtr) -> sizet
extern def PyMapping_HasKey(obj: PyObject | t.CPtr, key: PyObject | t.CPtr) -> int
extern def PyMapping_HasKeyString(obj: PyObject | t.CPtr, key: const str) -> int
extern def PyMapping_GetItemString(obj: PyObject | t.CPtr, key: const str) -> PyObject | t.CPtr
extern def PyMapping_SetItemString(obj: PyObject | t.CPtr, key: const str, val: PyObject | t.CPtr) -> int
extern def PyMapping_Keys(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyMapping_Values(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyMapping_Items(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyMapping_Check(obj: PyObject*) -> int
extern def PyMapping_Size(obj: PyObject*) -> sizet
extern def PyMapping_Length(obj: PyObject*) -> sizet
extern def PyMapping_HasKey(obj: PyObject*, key: PyObject*) -> int
extern def PyMapping_HasKeyString(obj: PyObject*, key: const str) -> int
extern def PyMapping_GetItemString(obj: PyObject*, key: const str) -> PyObject*
extern def PyMapping_SetItemString(obj: PyObject*, key: const str, val: PyObject*) -> int
extern def PyMapping_Keys(obj: PyObject*) -> PyObject*
extern def PyMapping_Values(obj: PyObject*) -> PyObject*
extern def PyMapping_Items(obj: PyObject*) -> PyObject*
# ============================================================
# 数字操作
# ============================================================
extern def PyNumber_Add(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Subtract(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Multiply(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_MatrixMultiply(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_FloorDivide(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_TrueDivide(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Modulo(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Power(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr, o3: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Negative(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Positive(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Absolute(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Invert(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Lshift(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Rshift(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_And(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Xor(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Or(o1: PyObject | t.CPtr, o2: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Index(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Long(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Float(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyNumber_Check(obj: PyObject | t.CPtr) -> int
extern def PyNumber_Add(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_Subtract(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_Multiply(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_MatrixMultiply(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_FloorDivide(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_TrueDivide(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_Modulo(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_Power(o1: PyObject*, o2: PyObject*, o3: PyObject*) -> PyObject*
extern def PyNumber_Negative(obj: PyObject*) -> PyObject*
extern def PyNumber_Positive(obj: PyObject*) -> PyObject*
extern def PyNumber_Absolute(obj: PyObject*) -> PyObject*
extern def PyNumber_Invert(obj: PyObject*) -> PyObject*
extern def PyNumber_Lshift(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_Rshift(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_And(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_Xor(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_Or(o1: PyObject*, o2: PyObject*) -> PyObject*
extern def PyNumber_Index(obj: PyObject*) -> PyObject*
extern def PyNumber_Long(obj: PyObject*) -> PyObject*
extern def PyNumber_Float(obj: PyObject*) -> PyObject*
extern def PyNumber_Check(obj: PyObject*) -> int
# ============================================================
# 弱引用
# ============================================================
extern def PyWeakref_NewRef(obj: PyObject | t.CPtr, cb: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyWeakref_GetObject(ref: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyWeakref_Check(obj: PyObject | t.CPtr) -> int
extern def PyWeakref_NewRef(obj: PyObject*, cb: PyObject*) -> PyObject*
extern def PyWeakref_GetObject(ref: PyObject*) -> PyObject*
extern def PyWeakref_Check(obj: PyObject*) -> int
# ============================================================
@@ -547,11 +547,11 @@ class PyMemberDef:
# ============================================================
# sys 模块
# ============================================================
extern def PySys_GetObject(name: const str) -> PyObject | t.CPtr
extern def PySys_SetObject(name: const str, val: PyObject | t.CPtr) -> int
extern def PySys_GetObject(name: const str) -> PyObject*
extern def PySys_SetObject(name: const str, val: PyObject*) -> int
extern def PySys_ResetWarnOptions(): pass
extern def PySys_AddWarnOption(s: PyObject | t.CPtr): pass
extern def PySYS_AddXOption(s: PyObject | t.CPtr): pass
extern def PySys_AddWarnOption(s: PyObject*): pass
extern def PySYS_AddXOption(s: PyObject*): pass
extern def PySys_WriteStdout(fmt: const str): pass
extern def PySys_WriteStderr(fmt: const str): pass
extern def PySys_FormatStdout(fmt: const str): pass
@@ -561,33 +561,33 @@ extern def PySys_FormatStderr(fmt: const str): pass
# ============================================================
# 内存视图
# ============================================================
extern def PyMemoryView_FromObject(obj: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyMemoryView_GetContiguous(obj: PyObject | t.CPtr, btype: int, order: char) -> PyObject | t.CPtr
extern def PyMemoryView_Check(obj: PyObject | t.CPtr) -> int
extern def PyMemoryView_FromObject(obj: PyObject*) -> PyObject*
extern def PyMemoryView_GetContiguous(obj: PyObject*, btype: int, order: char) -> PyObject*
extern def PyMemoryView_Check(obj: PyObject*) -> int
# ============================================================
# set / frozenset
# ============================================================
extern def PySet_New(iterable: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PySet_Add(s: PyObject | t.CPtr, key: PyObject | t.CPtr) -> int
extern def PySet_Discard(s: PyObject | t.CPtr, key: PyObject | t.CPtr) -> int
extern def PySet_Contains(s: PyObject | t.CPtr, key: PyObject | t.CPtr) -> int
extern def PySet_Size(s: PyObject | t.CPtr) -> sizet
extern def PySet_Clear(s: PyObject | t.CPtr): pass
extern def PySet_Check(obj: PyObject | t.CPtr) -> int
extern def PyFrozenSet_New(iterable: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PyFrozenSet_Check(obj: PyObject | t.CPtr) -> int
extern def PySet_New(iterable: PyObject*) -> PyObject*
extern def PySet_Add(s: PyObject*, key: PyObject*) -> int
extern def PySet_Discard(s: PyObject*, key: PyObject*) -> int
extern def PySet_Contains(s: PyObject*, key: PyObject*) -> int
extern def PySet_Size(s: PyObject*) -> sizet
extern def PySet_Clear(s: PyObject*): pass
extern def PySet_Check(obj: PyObject*) -> int
extern def PyFrozenSet_New(iterable: PyObject*) -> PyObject*
extern def PyFrozenSet_Check(obj: PyObject*) -> int
# ============================================================
# slice
# ============================================================
extern def PySlice_New(start: PyObject | t.CPtr, stop: PyObject | t.CPtr, step: PyObject | t.CPtr) -> PyObject | t.CPtr
extern def PySlice_GetIndicesEx(sl: PyObject | t.CPtr, length: sizet, start: sizet | t.CPtr, stop: sizet | t.CPtr, step: sizet | t.CPtr, slicelen: sizet | t.CPtr) -> int
extern def PySlice_Unpack(sl: PyObject | t.CPtr, start: t.CPtrDiffT | t.CPtr, stop: t.CPtrDiffT | t.CPtr, step: t.CPtrDiffT | t.CPtr): pass
extern def PySlice_AdjustIndices(length: sizet, start: t.CPtrDiffT | t.CPtr, stop: t.CPtrDiffT | t.CPtr, step: t.CPtrDiffT) -> sizet
extern def PySlice_Check(obj: PyObject | t.CPtr) -> int
extern def PySlice_New(start: PyObject*, stop: PyObject*, step: PyObject*) -> PyObject*
extern def PySlice_GetIndicesEx(sl: PyObject*, length: sizet, start: sizet*, stop: sizet*, step: sizet*, slicelen: sizet*) -> int
extern def PySlice_Unpack(sl: PyObject*, start: t.CPtrDiffT*, stop: t.CPtrDiffT*, step: t.CPtrDiffT*): pass
extern def PySlice_AdjustIndices(length: sizet, start: t.CPtrDiffT*, stop: t.CPtrDiffT*, step: t.CPtrDiffT) -> sizet
extern def PySlice_Check(obj: PyObject*) -> int
# ============================================================
@@ -596,41 +596,41 @@ extern def PySlice_Check(obj: PyObject | t.CPtr) -> int
# --- PyLongObj: Python 整数包装 ---
class PyLongObj:
ptr: PyObject | t.CPtr
ptr: PyObject*
def __new__(self) -> 'PyLongObj' | t.CPtr:
return t.CPtr(malloc(PyLongObj.__sizeof__()))
@staticmethod
def from_long(val: t.CLong) -> 'PyLongObj' | t.CPtr:
obj: PyLongObj | t.CPtr = PyLongObj()
obj: PyLongObj* = PyLongObj()
obj.ptr = PyLong_FromLong(val)
return obj
def __add__(self, other: PyLongObj | t.CPtr) -> 'PyLongObj' | t.CPtr:
res: PyLongObj | t.CPtr = PyLongObj()
def __add__(self, other: PyLongObj*) -> 'PyLongObj' | t.CPtr:
res: PyLongObj* = PyLongObj()
res.ptr = PyNumber_Add(self.ptr, other.ptr)
return res
def __sub__(self, other: PyLongObj | t.CPtr) -> 'PyLongObj' | t.CPtr:
res: PyLongObj | t.CPtr = PyLongObj()
def __sub__(self, other: PyLongObj*) -> 'PyLongObj' | t.CPtr:
res: PyLongObj* = PyLongObj()
res.ptr = PyNumber_Subtract(self.ptr, other.ptr)
return res
def __mul__(self, other: PyLongObj | t.CPtr) -> 'PyLongObj' | t.CPtr:
res: PyLongObj | t.CPtr = PyLongObj()
def __mul__(self, other: PyLongObj*) -> 'PyLongObj' | t.CPtr:
res: PyLongObj* = PyLongObj()
res.ptr = PyNumber_Multiply(self.ptr, other.ptr)
return res
def __neg__(self) -> 'PyLongObj' | t.CPtr:
res: PyLongObj | t.CPtr = PyLongObj()
res: PyLongObj* = PyLongObj()
res.ptr = PyNumber_Negative(self.ptr)
return res
def to_long(self) -> t.CLong:
return PyLong_AsLong(self.ptr)
def __str__(self) -> PyObject | t.CPtr:
def __str__(self) -> PyObject*:
return PyObject_Str(self.ptr)
def dec_ref(self):
@@ -639,46 +639,46 @@ class PyLongObj:
# --- PyFloatObj: Python 浮点数包装 ---
class PyFloatObj:
ptr: PyObject | t.CPtr
ptr: PyObject*
def __new__(self) -> 'PyFloatObj' | t.CPtr:
return t.CPtr(malloc(PyFloatObj.__sizeof__()))
@staticmethod
def from_double(val: double) -> 'PyFloatObj' | t.CPtr:
obj: PyFloatObj | t.CPtr = PyFloatObj()
obj: PyFloatObj* = PyFloatObj()
obj.ptr = PyFloat_FromDouble(val)
return obj
def __add__(self, other: PyFloatObj | t.CPtr) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj | t.CPtr = PyFloatObj()
def __add__(self, other: PyFloatObj*) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_Add(self.ptr, other.ptr)
return res
def __sub__(self, other: PyFloatObj | t.CPtr) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj | t.CPtr = PyFloatObj()
def __sub__(self, other: PyFloatObj*) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_Subtract(self.ptr, other.ptr)
return res
def __mul__(self, other: PyFloatObj | t.CPtr) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj | t.CPtr = PyFloatObj()
def __mul__(self, other: PyFloatObj*) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_Multiply(self.ptr, other.ptr)
return res
def __truediv__(self, other: PyFloatObj | t.CPtr) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj | t.CPtr = PyFloatObj()
def __truediv__(self, other: PyFloatObj*) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_TrueDivide(self.ptr, other.ptr)
return res
def __neg__(self) -> 'PyFloatObj' | t.CPtr:
res: PyFloatObj | t.CPtr = PyFloatObj()
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_Negative(self.ptr)
return res
def to_double(self) -> double:
return PyFloat_AsDouble(self.ptr)
def __str__(self) -> PyObject | t.CPtr:
def __str__(self) -> PyObject*:
return PyObject_Str(self.ptr)
def dec_ref(self):
@@ -687,29 +687,29 @@ class PyFloatObj:
# --- PyUnicodeObj: Python 字符串包装 ---
class PyUnicodeObj:
ptr: PyObject | t.CPtr
ptr: PyObject*
def __new__(self) -> 'PyUnicodeObj' | t.CPtr:
return t.CPtr(malloc(PyUnicodeObj.__sizeof__()))
@staticmethod
def from_string(s: char | t.CPtr) -> 'PyUnicodeObj' | t.CPtr:
obj: PyUnicodeObj | t.CPtr = PyUnicodeObj()
def from_string(s: char*) -> 'PyUnicodeObj' | t.CPtr:
obj: PyUnicodeObj* = PyUnicodeObj()
obj.ptr = PyUnicode_FromString(s)
return obj
def __add__(self, other: PyUnicodeObj | t.CPtr) -> 'PyUnicodeObj' | t.CPtr:
res: PyUnicodeObj | t.CPtr = PyUnicodeObj()
def __add__(self, other: PyUnicodeObj*) -> 'PyUnicodeObj' | t.CPtr:
res: PyUnicodeObj* = PyUnicodeObj()
res.ptr = PyUnicode_Concat(self.ptr, other.ptr)
return res
def __len__(self) -> t.CPtrDiffT:
return PyUnicode_GetLength(self.ptr)
def as_utf8(self) -> char | t.CPtr:
def as_utf8(self) -> char*:
return PyUnicode_AsUTF8(self.ptr)
def __str__(self) -> PyObject | t.CPtr:
def __str__(self) -> PyObject*:
return self.ptr
def dec_ref(self):
@@ -718,27 +718,27 @@ class PyUnicodeObj:
# --- PyListObj: Python 列表包装 ---
class PyListObj:
ptr: PyObject | t.CPtr
ptr: PyObject*
def __new__(self) -> 'PyListObj' | t.CPtr:
return t.CPtr(malloc(PyListObj.__sizeof__()))
@staticmethod
def new() -> 'PyListObj' | t.CPtr:
obj: PyListObj | t.CPtr = PyListObj()
obj: PyListObj* = PyListObj()
obj.ptr = PyList_New(0)
return obj
def __getitem__(self, idx: sizet) -> PyObject | t.CPtr:
def __getitem__(self, idx: sizet) -> PyObject*:
return PyList_GetItem(self.ptr, idx)
def __setitem__(self, idx: sizet, val: PyObject | t.CPtr):
def __setitem__(self, idx: sizet, val: PyObject*):
PyList_SetItem(self.ptr, idx, val)
def __len__(self) -> sizet:
return PyList_Size(self.ptr)
def append(self, item: PyObject | t.CPtr) -> int:
def append(self, item: PyObject*) -> int:
return PyList_Append(self.ptr, item)
def dec_ref(self):
@@ -747,30 +747,30 @@ class PyListObj:
# --- PyDictObj: Python 字典包装 ---
class PyDictObj:
ptr: PyObject | t.CPtr
ptr: PyObject*
def __new__(self) -> 'PyDictObj' | t.CPtr:
return t.CPtr(malloc(PyDictObj.__sizeof__()))
@staticmethod
def new() -> 'PyDictObj' | t.CPtr:
obj: PyDictObj | t.CPtr = PyDictObj()
obj: PyDictObj* = PyDictObj()
obj.ptr = PyDict_New()
return obj
def __getitem__(self, key: PyObject | t.CPtr) -> PyObject | t.CPtr:
def __getitem__(self, key: PyObject*) -> PyObject*:
return PyDict_GetItem(self.ptr, key)
def __setitem__(self, key: PyObject | t.CPtr, val: PyObject | t.CPtr):
def __setitem__(self, key: PyObject*, val: PyObject*):
PyDict_SetItem(self.ptr, key, val)
def __len__(self) -> sizet:
return PyDict_Size(self.ptr)
def get_string(self, key: char | t.CPtr) -> PyObject | t.CPtr:
def get_string(self, key: char*) -> PyObject*:
return PyDict_GetItemString(self.ptr, key)
def set_string(self, key: char | t.CPtr, val: PyObject | t.CPtr):
def set_string(self, key: char*, val: PyObject*):
PyDict_SetItemString(self.ptr, key, val)
def dec_ref(self):
+10 -24
View File
@@ -16,11 +16,11 @@ class Point3D():
class Student():
name: char | t.CPtr
name: char*
age: int
score: int
def __init__(self, n: char | t.CPtr, a: int, s: int):
def __init__(self, n: char*, a: int, s: int):
self.name = n
self.age = a
self.score = s
@@ -157,14 +157,10 @@ def TestClassWithBitFields():
def TestIntArray():
stdio.printf("=== Test Int Array ===\n")
arr: t.CArray[int, 5] = t.CArray[int, 5]()
i: int = 0
while i < 5:
for i in range(5):
arr[i] = i * 10
i += 1
i = 0
while i < 5:
for i in range(5):
stdio.printf("arr[%d]=%d\n", i, arr[i])
i += 1
def TestFloatArray():
@@ -174,10 +170,8 @@ def TestFloatArray():
farr[1] = 2.5
farr[2] = 3.5
farr[3] = 4.5
i: int = 0
while i < 4:
for i in range(4):
stdio.printf("farr[%d]=%.1f\n", i, farr[i])
i += 1
def TestCharArray():
@@ -202,30 +196,22 @@ def TestNestedArray():
row1[0] = 10
row1[1] = 11
row1[2] = 12
i: int = 0
while i < 3:
for i in range(3):
stdio.printf("row0[%d]=%d ", i, row0[i])
i += 1
stdio.printf("\n")
i = 0
while i < 3:
for i in range(3):
stdio.printf("row1[%d]=%d ", i, row1[i])
i += 1
stdio.printf("\n")
def TestArrayWithStruct():
stdio.printf("=== Test Array with Struct ===\n")
points: t.CArray[SimpleData, 3] = t.CArray[SimpleData, 3]()
i: int = 0
while i < 3:
for i in range(3):
points[i].x = i * 10
points[i].y = i * 100
i += 1
i = 0
while i < 3:
for i in range(3):
stdio.printf("Point[%d]: x=%d, y=%d\n", i, points[i].x, points[i].y)
i += 1
def TestArrayPointer():
@@ -234,7 +220,7 @@ def TestArrayPointer():
data[0] = 100
data[1] = 200
data[2] = 300
ptr: int | t.CPtr = data
ptr: int* = data
stdio.printf("ptr[0]=%d\n", ptr[0])
stdio.printf("ptr[1]=%d\n", ptr[1])
stdio.printf("ptr[2]=%d\n", ptr[2])
+1 -3
View File
@@ -170,10 +170,8 @@ export def echo(msg: str):
@log
export def power(base: int, exp: int) -> int:
result: int = 1
i: int = 0
while i < exp:
for i in range(exp):
result = result * base
i = i + 1
return result
+17 -19
View File
@@ -17,7 +17,7 @@ def main() -> CInt | CExport:
# 分配内存竞技场
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
# === Test 1: dict set_int / c.Deref 基本操作 ===
testcheck.section("Test 1: dict set_int / c.Deref 基本操作")
@@ -38,10 +38,10 @@ def main() -> CInt | CExport:
stdio.printf("p2=%p\n", p2)
p3: t.CPtr = d["gamma"]
stdio.printf("p3=%p\n", p3)
v1: int = *(int | t.CPtr)(p1)
v1: int = *(int*)(p1)
stdio.printf("v1=%d\n", v1)
v2: int = *(int | t.CPtr)(p2)
v3: int = *(int | t.CPtr)(p3)
v2: int = *(int*)(p2)
v3: int = *(int*)(p3)
stdio.printf("alpha=%d beta=%d gamma=%d\n", v1, v2, v3)
testcheck.check(v1 == 10, "dict[alpha]==10 OK", "dict[alpha] FAILED")
testcheck.check(v2 == 20, "dict[beta]==20 OK", "dict[beta] FAILED")
@@ -51,7 +51,7 @@ def main() -> CInt | CExport:
testcheck.section("Test 2: 更新已有键")
d.set_int("beta", 99)
p2b: t.CPtr = d["beta"]
v2b: int = *(int | t.CPtr)(p2b)
v2b: int = *(int*)(p2b)
stdio.printf("beta(updated)=%d\n", v2b)
testcheck.check(v2b == 99, "dict update OK", "dict update FAILED")
testcheck.check(len(d) == 3, "dict len still 3 OK", "dict len changed FAILED")
@@ -62,7 +62,7 @@ def main() -> CInt | CExport:
testcheck.check(gv == None, "dict get missing OK (None)", "dict get missing FAILED")
gp: t.CPtr = d.get("alpha", None)
ga: int = *(int | t.CPtr)(gp)
ga: int = *(int*)(gp)
stdio.printf("get(alpha)=%d\n", ga)
testcheck.check(ga == 10, "dict get existing OK", "dict get existing FAILED")
@@ -79,7 +79,7 @@ def main() -> CInt | CExport:
iter_count: int = 0
for key in d:
kp: t.CPtr = d[key]
val: int = *(int | t.CPtr)(kp)
val: int = *(int*)(kp)
stdio.printf("dict[%s]=%d\n", key, val)
iter_count += 1
testcheck.check(iter_count == 3, "dict iter OK (3)", "dict iter FAILED")
@@ -119,12 +119,10 @@ def main() -> CInt | CExport:
# === Test 8: 扩容测试 ===
testcheck.section("Test 8: 扩容测试 (>8 个元素)")
d3: dict = dict(bd)
i: int = 0
while i < 20:
for i in range(20):
key_buf: str = stdlib.malloc(16)
stdio.sprintf(key_buf, "key%d", i)
d3.set_int(key_buf, i * 100)
i += 1
n3: sizet = len(d3)
stdio.printf("d3 len=%lu (after 20 inserts)\n", n3)
testcheck.check(n3 == 20, "dict expand OK (20)", "dict expand FAILED")
@@ -133,14 +131,14 @@ def main() -> CInt | CExport:
k5: str = stdlib.malloc(16)
stdio.sprintf(k5, "key5")
p5: t.CPtr = d3[k5]
v5: int = *(int | t.CPtr)(p5)
v5: int = *(int*)(p5)
stdio.printf("d3[key5]=%d\n", v5)
testcheck.check(v5 == 500, "dict expand key5 OK", "dict expand key5 FAILED")
k15: str = stdlib.malloc(16)
stdio.sprintf(k15, "key15")
p15: t.CPtr = d3[k15]
v15: int = *(int | t.CPtr)(p15)
v15: int = *(int*)(p15)
stdio.printf("d3[key15]=%d\n", v15)
testcheck.check(v15 == 1500, "dict expand key15 OK", "dict expand key15 FAILED")
@@ -165,9 +163,9 @@ def main() -> CInt | CExport:
xp: t.CPtr = jd2["x"]
yp: t.CPtr = jd2["y"]
zp: t.CPtr = jd2["z"]
xv: int = *(int | t.CPtr)(xp)
yv: int = *(int | t.CPtr)(yp)
zv: int = *(int | t.CPtr)(zp)
xv: int = *(int*)(xp)
yv: int = *(int*)(yp)
zv: int = *(int*)(zp)
stdio.printf("loads: x=%d y=%d z=%d\n", xv, yv, zv)
testcheck.check(xv == 1, "loads x OK", "loads x FAILED")
testcheck.check(yv == 2, "loads y OK", "loads y FAILED")
@@ -194,8 +192,8 @@ def main() -> CInt | CExport:
rt2.loads(pool, rt_str)
rta_p: t.CPtr = rt2["a"]
rtb_p: t.CPtr = rt2["b"]
rta: int = *(int | t.CPtr)(rta_p)
rtb: int = *(int | t.CPtr)(rtb_p)
rta: int = *(int*)(rta_p)
rtb: int = *(int*)(rtb_p)
stdio.printf("round-trip: a=%d b=%d\n", rta, rtb)
testcheck.check(rta == 1, "round-trip a OK", "round-trip a FAILED")
testcheck.check(rtb == 2, "round-trip b OK", "round-trip b FAILED")
@@ -211,8 +209,8 @@ def main() -> CInt | CExport:
sub: dict* = outer["sub"]
sa_p: t.CPtr = sub["a"]
sb_p: t.CPtr = sub["b"]
sa: int = *(int | t.CPtr)(sa_p)
sb: int = *(int | t.CPtr)(sb_p)
sa: int = *(int*)(sa_p)
sb: int = *(int*)(sb_p)
stdio.printf("nested: sub.a=%d sub.b=%d\n", sa, sb)
testcheck.check(sa == 1, "nested sub.a OK", "nested sub.a FAILED")
testcheck.check(sb == 2, "nested sub.b OK", "nested sub.b FAILED")
+7 -7
View File
@@ -32,7 +32,7 @@ def main() -> CInt | CExport:
# upper() 测试: 通过 mbuddy 分配内存,返回大写字符串
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
# 直接字段赋值: a.__mbuddy__ = bd (语法糖, 等价于 a.set_mbuddy(bd))
a.__mbuddy__ = bd
@@ -43,7 +43,7 @@ def main() -> CInt | CExport:
b: str = "World"
# 直接字段读取: b.__mbuddy__ (应返回 NULL)
b_buddy: memhub.MemBuddy | t.CPtr = b.__mbuddy__
b_buddy: memhub.MemBuddy* = b.__mbuddy__
if int(b_buddy) == 0:
stdio.printf("mbuddy OK: b.__mbuddy__ is NULL (no pollution)\n")
else:
@@ -231,7 +231,7 @@ def main() -> CInt | CExport:
w_str: str = "WithTest"
# 验证 __mbuddy__ 已自动注入(非 NULL)
w_buddy: memhub.MemBuddy | t.CPtr = w_str.__mbuddy__
w_buddy: memhub.MemBuddy* = w_str.__mbuddy__
testcheck.check(int(w_buddy) != 0, "with inject OK: __mbuddy__ auto-injected", "with inject FAIL: __mbuddy__ is NULL")
# upper() 不需要手动设置 __mbuddy__
@@ -253,11 +253,11 @@ def main() -> CInt | CExport:
# 验证多个 str 变量都获得注入
w_str2: str = "Multiple"
w_buddy2: memhub.MemBuddy | t.CPtr = w_str2.__mbuddy__
w_buddy2: memhub.MemBuddy* = w_str2.__mbuddy__
testcheck.check(int(w_buddy2) != 0, "with multi inject OK", "with multi inject FAIL")
test_s: str = "www.gvsds.com"
list_s: list[str] | t.CPtr = test_s.split('.')
list_s: list[str]* = test_s.split('.')
# 迭代器测试: for idx, i in zip(range(len(list_s)), list_s)
iter_count: int = 0
for iter_idx, i in zip(range(len(list_s)), list_s):
@@ -271,8 +271,8 @@ def main() -> CInt | CExport:
testcheck.section("Test 10: zip(list, list) 元组解包")
za: str = "a,b,c"
zb: str = "1,2,3"
list_a: list[str] | t.CPtr = za.split(',')
list_b: list[str] | t.CPtr = zb.split(',')
list_a: list[str]* = za.split(',')
list_b: list[str]* = zb.split(',')
zip_idx: int = 0
for ca, cb in zip(list_a, list_b):
stdio.printf("zip[%d]: '%s'='%s'\n", zip_idx, ca, cb)
+6 -6
View File
@@ -26,7 +26,7 @@ def test_for_in_str():
def test_for_in_list():
testcheck.section("Test 3: for v in list[str]")
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
lst: list[str] = list[str](bd)
lst.append("x")
lst.append("y")
@@ -42,7 +42,7 @@ def test_for_in_list():
def test_zip_list_list():
testcheck.section("Test 4: zip(list, list)")
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
la: list[str] = list[str](bd)
la.append("a")
la.append("b")
@@ -62,7 +62,7 @@ def test_zip_list_list():
def test_zip_range_list():
testcheck.section("Test 5: zip(range, list)")
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
lst: list[str] = list[str](bd)
lst.append("p")
lst.append("q")
@@ -89,7 +89,7 @@ def test_zip_str_str():
def test_zip_range_len_list():
testcheck.section("Test 7: zip(range(len), list)")
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
lst: list[str] = list[str](bd)
lst.append("www")
lst.append("gvsds")
@@ -105,7 +105,7 @@ def test_zip_range_len_list():
def test_enumerate_list():
testcheck.section("Test 8: enumerate(list)")
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
lst: list[str] = list[str](bd)
lst.append("alpha")
lst.append("beta")
@@ -183,7 +183,7 @@ def test_for_else_empty_range():
def test_for_else_list():
testcheck.section("Test 14: for-else (list[str] 迭代耗尽 → 执行 else)")
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
lst: list[str] = list[str](bd)
lst.append("a")
lst.append("b")
+4 -4
View File
@@ -36,10 +36,10 @@ export def main() -> int:
print("Assigned: ", s)
# ctraits.isptr 编译时类型判断测试
# c.Addr(s) 取的是局部变量 s(str = i8*)的地址,结果是 i8**(char**);
# 与 INTPTR(= t.CInt | t.CPtr,int*,见 includes/stdint.vp)层数与基座都不同,
# 且指针隐式转换已收紧(层数必须相同)⇒ 注解按实际类型写 str | t.CPtr(= i8**)。
ptr_var: str | t.CPtr = &s
# &s 取的是局部变量 s(str = i8*)的地址,结果是 i8**(char**);
# 与 INTPTR(= int*,见 includes/stdint.vp)层数与基座都不同,
# 且指针隐式转换已收紧(层数必须相同)⇒ 注解按实际类型写 str*(= i8**)。
ptr_var: str* = &s
val_var: int = 42
if c.CIf(ctraits.isptr(ptr_var)):
print("ptr_var is pointer")
+6 -6
View File
@@ -13,11 +13,11 @@ from g4node import G4Node, new_g4node
# ============================================================
def caller1_make_chain(pool: memhub.MemBuddy | t.CPtr) -> G4Node | t.CPtr:
def caller1_make_chain(pool: memhub.MemBuddy*) -> G4Node*:
"""创建 3 节点链表,直接访问 Next 字段"""
a: G4Node | t.CPtr = new_g4node(pool)
b: G4Node | t.CPtr = new_g4node(pool)
c: G4Node | t.CPtr = new_g4node(pool)
a: G4Node* = new_g4node(pool)
b: G4Node* = new_g4node(pool)
c: G4Node* = new_g4node(pool)
if a is None or b is None or c is None:
return None
a.IntVal = 100
@@ -29,12 +29,12 @@ def caller1_make_chain(pool: memhub.MemBuddy | t.CPtr) -> G4Node | t.CPtr:
return a
def caller1_sum_chain(head: G4Node | t.CPtr) -> int:
def caller1_sum_chain(head: G4Node*) -> int:
"""遍历链表求和,直接访问 Next 字段"""
if head is None:
return 0
total: int = head.IntVal
cur: G4Node | t.CPtr = head
cur: G4Node* = head
# 直接访问 Next 字段(不通过 g4node_get_next 访问器)
while cur.Next is not None:
cur = cur.Next
+6 -6
View File
@@ -12,24 +12,24 @@ from g4node import G4Node, new_g4node
# ============================================================
def caller2_reverse_chain(head: G4Node | t.CPtr) -> G4Node | t.CPtr:
def caller2_reverse_chain(head: G4Node*) -> G4Node*:
"""反转链表,直接访问 Next 字段"""
if head is None:
return None
prev: G4Node | t.CPtr = None
cur: G4Node | t.CPtr = head
prev: G4Node* = None
cur: G4Node* = head
while cur is not None:
nxt: G4Node | t.CPtr = cur.Next
nxt: G4Node* = cur.Next
cur.Next = prev
prev = cur
cur = nxt
return prev
def caller2_count_nodes(head: G4Node | t.CPtr) -> int:
def caller2_count_nodes(head: G4Node*) -> int:
"""计算链表节点数"""
count: int = 0
cur: G4Node | t.CPtr = head
cur: G4Node* = head
while cur is not None:
count = count + 1
cur = cur.Next
+4 -4
View File
@@ -12,20 +12,20 @@ from g4node import G4Node, new_g4node
# ============================================================
def caller3_find_tail(head: G4Node | t.CPtr) -> G4Node | t.CPtr:
def caller3_find_tail(head: G4Node*) -> G4Node*:
"""找到链表尾部节点,直接访问 Next"""
if head is None:
return None
cur: G4Node | t.CPtr = head
cur: G4Node* = head
while cur.Next is not None:
cur = cur.Next
return cur
def caller3_append(head: G4Node | t.CPtr, new_node: G4Node | t.CPtr) -> G4Node | t.CPtr:
def caller3_append(head: G4Node*, new_node: G4Node*) -> G4Node*:
"""在链表末尾追加节点"""
if head is None:
return new_node
tail: G4Node | t.CPtr = caller3_find_tail(head)
tail: G4Node* = caller3_find_tail(head)
tail.Next = new_node
return head
+19 -19
View File
@@ -24,8 +24,8 @@ def test_g4node_create():
if arena is None:
testcheck.check(False, "malloc arena", "FAIL")
return
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 4096)
n: G4Node | t.CPtr = new_g4node(pool)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, 4096)
n: G4Node* = new_g4node(pool)
if n is None:
testcheck.check(False, "new_g4node", "FAIL")
return
@@ -40,16 +40,16 @@ def test_g4node_next_field():
if arena is None:
testcheck.check(False, "malloc arena", "FAIL")
return
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 4096)
n1: G4Node | t.CPtr = new_g4node(pool)
n2: G4Node | t.CPtr = new_g4node(pool)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, 4096)
n1: G4Node* = new_g4node(pool)
n2: G4Node* = new_g4node(pool)
if n1 is None or n2 is None:
testcheck.check(False, "new_g4node", "FAIL")
return
n1.IntVal = 10
n2.IntVal = 20
g4node_set_next(n1, n2)
next_node: G4Node | t.CPtr = g4node_get_next(n1)
next_node: G4Node* = g4node_get_next(n1)
if next_node is None:
testcheck.check(False, "g4node_get_next", "FAIL")
return
@@ -63,10 +63,10 @@ def test_g4node_chain():
if arena is None:
testcheck.check(False, "malloc arena", "FAIL")
return
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 4096)
a: G4Node | t.CPtr = new_g4node(pool)
b: G4Node | t.CPtr = new_g4node(pool)
c: G4Node | t.CPtr = new_g4node(pool)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, 4096)
a: G4Node* = new_g4node(pool)
b: G4Node* = new_g4node(pool)
c: G4Node* = new_g4node(pool)
if a is None or b is None or c is None:
testcheck.check(False, "new_g4node", "FAIL")
return
@@ -76,7 +76,7 @@ def test_g4node_chain():
g4node_set_next(a, b)
g4node_set_next(b, c)
sum: int = a.IntVal
p: G4Node | t.CPtr = g4node_get_next(a)
p: G4Node* = g4node_get_next(a)
sum = sum + p.IntVal
p = g4node_get_next(p)
sum = sum + p.IntVal
@@ -90,8 +90,8 @@ def test_caller1_direct_access():
if arena is None:
testcheck.check(False, "malloc arena", "FAIL")
return
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 8192)
head: G4Node | t.CPtr = caller1.caller1_make_chain(pool)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, 8192)
head: G4Node* = caller1.caller1_make_chain(pool)
if head is None:
testcheck.check(False, "caller1_make_chain", "FAIL")
return
@@ -107,13 +107,13 @@ def test_caller2_reverse():
if arena is None:
testcheck.check(False, "malloc arena", "FAIL")
return
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 8192)
head: G4Node | t.CPtr = caller1.caller1_make_chain(pool)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, 8192)
head: G4Node* = caller1.caller1_make_chain(pool)
if head is None:
testcheck.check(False, "caller1_make_chain", "FAIL")
return
count_before: int = caller2.caller2_count_nodes(head)
reversed_head: G4Node | t.CPtr = caller2.caller2_reverse_chain(head)
reversed_head: G4Node* = caller2.caller2_reverse_chain(head)
count_after: int = caller2.caller2_count_nodes(reversed_head)
stdio.printf("caller2 count before=%d after=%d\n", count_before, count_after)
testcheck.check(count_before == 3 and count_after == 3,
@@ -127,12 +127,12 @@ def test_caller3_append():
if arena is None:
testcheck.check(False, "malloc arena", "FAIL")
return
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 8192)
head: G4Node | t.CPtr = caller1.caller1_make_chain(pool)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, 8192)
head: G4Node* = caller1.caller1_make_chain(pool)
if head is None:
testcheck.check(False, "caller1_make_chain", "FAIL")
return
extra: G4Node | t.CPtr = new_g4node(pool)
extra: G4Node* = new_g4node(pool)
if extra is None:
testcheck.check(False, "new_g4node", "FAIL")
return
+4 -4
View File
@@ -33,8 +33,8 @@ class G4Node(GSListNode[G4Node]):
# 工厂函数(与 __values.py 中的 new_value 类似)
def new_g4node(pool: memhub.MemBuddy | t.CPtr) -> G4Node | t.CPtr:
ptr: G4Node | t.CPtr = pool.alloc(48)
def new_g4node(pool: memhub.MemBuddy*) -> G4Node*:
ptr: G4Node* = pool.alloc(48)
if ptr:
ptr.Ty = None
ptr.Name = None
@@ -45,9 +45,9 @@ def new_g4node(pool: memhub.MemBuddy | t.CPtr) -> G4Node | t.CPtr:
return ptr
def g4node_get_next(node: G4Node | t.CPtr) -> G4Node | t.CPtr:
def g4node_get_next(node: G4Node*) -> G4Node*:
return node.Next
def g4node_set_next(node: G4Node | t.CPtr, next_node: G4Node | t.CPtr):
def g4node_set_next(node: G4Node*, next_node: G4Node*):
node.Next = next_node
+12 -12
View File
@@ -32,10 +32,10 @@ define GSLIST_SIZE = 24 # Head(8) + Tail(8) + Count(8)
@t.NoVTable
class G5ListWrapper:
List: GSList[G5Node] | t.CPtr
List: GSList[G5Node]*
def __init__(self, pool: memhub.MemBuddy | t.CPtr):
gsl: GSList[G5Node] | t.CPtr = pool.alloc(GSLIST_SIZE)
def __init__(self, pool: memhub.MemBuddy*):
gsl: GSList[G5Node]* = pool.alloc(GSLIST_SIZE)
if gsl is None:
self.List = None
return
@@ -76,13 +76,13 @@ def test_g5node_next():
def test_gslist_create():
testcheck.section("Test 3: GSList[G5Node] create")
lst: GSList[G5Node] | t.CPtr = GSList[G5Node]()
lst: GSList[G5Node]* = GSList[G5Node]()
if lst is None:
testcheck.check(False, "GSList[G5Node]() is None", "FAIL")
return
# 检查初始状态
head: G5Node | t.CPtr = lst.Head
tail: G5Node | t.CPtr = lst.Tail
head: G5Node* = lst.Head
tail: G5Node* = lst.Tail
count: sizet = lst.Count
testcheck.check(head is None, "initial Head is None", "expect None")
testcheck.check(tail is None, "initial Tail is None", "expect None")
@@ -91,7 +91,7 @@ def test_gslist_create():
def test_gslist_append():
testcheck.section("Test 4: GSList[G5Node].append 3 nodes")
lst: GSList[G5Node] | t.CPtr = GSList[G5Node]()
lst: GSList[G5Node]* = GSList[G5Node]()
if lst is None:
testcheck.check(False, "GSList[G5Node]() is None", "FAIL")
return
@@ -111,14 +111,14 @@ def test_gslist_append():
testcheck.check(count == 3, "Count = 3 after 3 appends", "expect 3")
# 验证 Head
head: G5Node | t.CPtr = lst.Head
head: G5Node* = lst.Head
if head is None:
testcheck.check(False, "Head is None", "FAIL")
return
testcheck.check(head.Value == 1, "Head.Value = 1", "expect 1")
# 验证 Tail
tail: G5Node | t.CPtr = lst.Tail
tail: G5Node* = lst.Tail
if tail is None:
testcheck.check(False, "Tail is None", "FAIL")
return
@@ -126,7 +126,7 @@ def test_gslist_append():
# 遍历链表验证顺序
sum: int = 0
cur: G5Node | t.CPtr = lst.Head
cur: G5Node* = lst.Head
while cur is not None:
sum = sum + cur.Value
cur = cur.Next
@@ -143,7 +143,7 @@ def test_wrapper_list_field():
if arena is None:
testcheck.check(False, "malloc arena", "FAIL")
return
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 4096)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, 4096)
wrapper: G5ListWrapper = G5ListWrapper(pool)
if wrapper is None:
testcheck.check(False, "G5ListWrapper(pool) is None", "FAIL")
@@ -157,7 +157,7 @@ def test_wrapper_list_field():
wrapper.List.append(n)
# 通过 wrapper.List 访问 GSList 字段
head: G5Node | t.CPtr = wrapper.List.Head
head: G5Node* = wrapper.List.Head
if head is None:
testcheck.check(False, "wrapper.List.Head is None", "FAIL")
return
+19 -19
View File
@@ -32,7 +32,7 @@ class G5Node(GSListNode[G5Node]):
@t.NoVTable
class G5Container:
List: GSList[G5Node] | t.CPtr
List: GSList[G5Node]*
# ============================================================
@@ -42,9 +42,9 @@ class G5Container:
# G5Node 硬编码大小: Next(8) + Value(4) + padding(4) = 16 字节
define G5NODE_SIZE = 16
def new_g5node(pool: memhub.MemBuddy | t.CPtr) -> G5Node | t.CPtr:
def new_g5node(pool: memhub.MemBuddy*) -> G5Node*:
"""从 pool 分配并零初始化一个 G5Node"""
ptr: G5Node | t.CPtr = pool.alloc(G5NODE_SIZE)
ptr: G5Node* = pool.alloc(G5NODE_SIZE)
if ptr is None: return None
string.memset(ptr, 0, G5NODE_SIZE)
return ptr
@@ -53,7 +53,7 @@ def new_g5node(pool: memhub.MemBuddy | t.CPtr) -> G5Node | t.CPtr:
# GSList 硬编码大小: Head(8) + Tail(8) + Count(8) = 24 字节
define G5LIST_SIZE = 24
def new_g5list(pool: memhub.MemBuddy | t.CPtr) -> GSList[G5Node] | t.CPtr:
def new_g5list(pool: memhub.MemBuddy*) -> GSList[G5Node]*:
"""从 pool 分配并零初始化一个 GSList 容器(Head/Tail/Count 全零)"""
gsl: t.CPtr = pool.alloc(G5LIST_SIZE)
if gsl is None: return None
@@ -64,9 +64,9 @@ def new_g5list(pool: memhub.MemBuddy | t.CPtr) -> GSList[G5Node] | t.CPtr:
# G5Container 硬编码大小: List(8) = 8 字节
define G5CONTAINER_SIZE = 8
def new_g5container(pool: memhub.MemBuddy | t.CPtr) -> G5Container | t.CPtr:
def new_g5container(pool: memhub.MemBuddy*) -> G5Container*:
"""从 pool 分配并零初始化一个 G5Container"""
ptr: G5Container | t.CPtr = pool.alloc(G5CONTAINER_SIZE)
ptr: G5Container* = pool.alloc(G5CONTAINER_SIZE)
if ptr is None: return None
string.memset(ptr, 0, G5CONTAINER_SIZE)
return ptr
@@ -83,43 +83,43 @@ def new_g5container(pool: memhub.MemBuddy | t.CPtr) -> G5Container | t.CPtr:
# 所有字段。其他模块通过函数调用获取字段值,绕过 stub 限制。
# ============================================================
def g5list_get_head(lst: GSList[G5Node] | t.CPtr) -> G5Node | t.CPtr:
def g5list_get_head(lst: GSList[G5Node]*) -> G5Node*:
"""获取链表头节点"""
if lst is None: return None
return lst.Head
def g5list_get_tail(lst: GSList[G5Node] | t.CPtr) -> G5Node | t.CPtr:
def g5list_get_tail(lst: GSList[G5Node]*) -> G5Node*:
"""获取链表尾节点"""
if lst is None: return None
return lst.Tail
def g5list_get_count(lst: GSList[G5Node] | t.CPtr) -> sizet:
def g5list_get_count(lst: GSList[G5Node]*) -> sizet:
"""获取链表节点数"""
if lst is None: return 0
return lst.Count
def g5list_set_head(lst: GSList[G5Node] | t.CPtr, node: G5Node | t.CPtr):
def g5list_set_head(lst: GSList[G5Node]*, node: G5Node*):
"""设置链表头节点"""
if lst is None: return
lst.Head = node
def g5list_set_tail(lst: GSList[G5Node] | t.CPtr, node: G5Node | t.CPtr):
def g5list_set_tail(lst: GSList[G5Node]*, node: G5Node*):
"""设置链表尾节点"""
if lst is None: return
lst.Tail = node
def g5list_set_count(lst: GSList[G5Node] | t.CPtr, count: sizet):
def g5list_set_count(lst: GSList[G5Node]*, count: sizet):
"""设置链表节点数"""
if lst is None: return
lst.Count = count
def g5list_append(lst: GSList[G5Node] | t.CPtr, node: G5Node | t.CPtr):
def g5list_append(lst: GSList[G5Node]*, node: G5Node*):
"""将 node 追加到链表末尾(O(1))
直接操作 Head/Tail/Count 字段,不依赖 GSList.append 方法
@@ -139,22 +139,22 @@ def g5list_append(lst: GSList[G5Node] | t.CPtr, node: G5Node | t.CPtr):
# G5Node 访问器
# ============================================================
def g5node_get_value(node: G5Node | t.CPtr) -> int:
def g5node_get_value(node: G5Node*) -> int:
if node is None: return 0
return node.Value
def g5node_set_value(node: G5Node | t.CPtr, value: int):
def g5node_set_value(node: G5Node*, value: int):
if node is None: return
node.Value = value
def g5node_get_next(node: G5Node | t.CPtr) -> G5Node | t.CPtr:
def g5node_get_next(node: G5Node*) -> G5Node*:
if node is None: return None
return node.Next
def g5node_set_next(node: G5Node | t.CPtr, next_node: G5Node | t.CPtr):
def g5node_set_next(node: G5Node*, next_node: G5Node*):
if node is None: return
node.Next = next_node
@@ -163,11 +163,11 @@ def g5node_set_next(node: G5Node | t.CPtr, next_node: G5Node | t.CPtr):
# G5Container 访问器
# ============================================================
def g5container_get_list(container: G5Container | t.CPtr) -> GSList[G5Node] | t.CPtr:
def g5container_get_list(container: G5Container*) -> GSList[G5Node]*:
if container is None: return None
return container.List
def g5container_set_list(container: G5Container | t.CPtr, lst: GSList[G5Node] | t.CPtr):
def g5container_set_list(container: G5Container*, lst: GSList[G5Node]*):
if container is None: return
container.List = lst
+2 -2
View File
@@ -24,8 +24,8 @@ def test_value_struct_fields():
if arena is None:
testcheck.check(False, "malloc arena", "FAIL")
return
pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 4096)
node: Value | t.CPtr = pool.alloc(48)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, 4096)
node: Value* = pool.alloc(48)
if node is None:
testcheck.check(False, "alloc Value", "FAIL")
return
+1 -1
View File
@@ -123,7 +123,7 @@ def main() -> CInt | CExport:
print(val_i32)
ptr_raw = stdlib.malloc(8)
ptr_typed = (int | t.CPtr)(ptr_raw)
ptr_typed = (int*)(ptr_raw)
viperlib.snprintf(buf, 256, "cast ptr=%p", ptr_typed)
print(buf)
+1 -1
View File
@@ -81,7 +81,7 @@ class IntPair:
a: int
b: int
def generic_swap(p: IntPair | t.CPtr):
def generic_swap(p: IntPair*):
tmp: int = (*p).a
(*p).a = (*p).b
(*p).b = tmp
+1 -1
View File
@@ -12,7 +12,7 @@ import w32.win32console
# ==============================================
# 工具函数:打印十六进制哈希串
# ==============================================
def print_hex(buf: uint8 | t.CPtr, length: int):
def print_hex(buf: uint8*, length: int):
for i in range(length):
stdio.printf("%02x", buf[i])
stdio.printf("\n")
+14 -18
View File
@@ -18,7 +18,7 @@ def main() -> CInt | CExport:
# 分配内存竞技场
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
# === Test 1: 基本插入和查找 ===
testcheck.section("Test 1: 基本插入和查找 (set_int)")
@@ -34,11 +34,11 @@ def main() -> CInt | CExport:
# 须给出有元素类型的指针:c.Deref 的宽度只认 pointee 类型,i8*(t.CPtr)恒读
# 1 字节,不再按赋值目标注解反推 4 字节。
p1: t.CPtr = ht["alpha"]
v1: int = *(int | t.CPtr)(p1)
v1: int = *(int*)(p1)
p2: t.CPtr = ht["beta"]
v2: int = *(int | t.CPtr)(p2)
v2: int = *(int*)(p2)
p3: t.CPtr = ht["gamma"]
v3: int = *(int | t.CPtr)(p3)
v3: int = *(int*)(p3)
stdio.printf("alpha=%d beta=%d gamma=%d\n", v1, v2, v3)
testcheck.check(v1 == 10, "ht[alpha]==10 OK", "ht[alpha] FAILED")
testcheck.check(v2 == 20, "ht[beta]==20 OK", "ht[beta] FAILED")
@@ -48,7 +48,7 @@ def main() -> CInt | CExport:
testcheck.section("Test 2: 更新已有键")
ht.set_int("beta", 99)
p2b: t.CPtr = ht["beta"]
v2b: int = *(int | t.CPtr)(p2b)
v2b: int = *(int*)(p2b)
stdio.printf("beta(updated)=%d\n", v2b)
testcheck.check(v2b == 99, "ht update OK", "ht update FAILED")
testcheck.check(len(ht) == 3, "ht len still 3 OK", "ht len changed FAILED")
@@ -58,7 +58,7 @@ def main() -> CInt | CExport:
gv: t.CPtr = ht.get("missing", None)
testcheck.check(gv == None, "ht get missing OK (None)", "ht get missing FAILED")
gp: t.CPtr = ht.get("alpha", None)
ga: int = *(int | t.CPtr)(gp)
ga: int = *(int*)(gp)
stdio.printf("get(alpha)=%d\n", ga)
testcheck.check(ga == 10, "ht get existing OK", "ht get existing FAILED")
@@ -87,7 +87,7 @@ def main() -> CInt | CExport:
testcheck.section("Test 6: 删除后重新插入")
ht.set_int("beta", 555)
p2c: t.CPtr = ht["beta"]
v2c: int = *(int | t.CPtr)(p2c)
v2c: int = *(int*)(p2c)
stdio.printf("beta(re-inserted)=%d\n", v2c)
testcheck.check(v2c == 555, "ht re-insert beta OK", "ht re-insert beta FAILED")
testcheck.check(len(ht) == 3, "ht len 3 after re-insert OK", "ht len after re-insert FAILED")
@@ -97,7 +97,7 @@ def main() -> CInt | CExport:
iter_count: int = 0
for key in ht:
kp: t.CPtr = ht[key]
val: int = *(int | t.CPtr)(kp)
val: int = *(int*)(kp)
stdio.printf("ht[%s]=%d\n", key, val)
iter_count += 1
testcheck.check(iter_count == 3, "ht iter OK (3)", "ht iter FAILED")
@@ -127,12 +127,10 @@ def main() -> CInt | CExport:
# === Test 9: 扩容测试 ===
testcheck.section("Test 9: 扩容测试 (>16 个元素)")
ht3: hashtable.HashTable = hashtable.HashTable(bd)
i: int = 0
while i < 50:
for i in range(50):
key_buf: str = stdlib.malloc(16)
stdio.sprintf(key_buf, "key%d", i)
ht3.set_int(key_buf, i * 100)
i += 1
n3: sizet = len(ht3)
stdio.printf("ht3 len=%lu (after 50 inserts)\n", n3)
testcheck.check(n3 == 50, "ht expand OK (50)", "ht expand FAILED")
@@ -141,21 +139,21 @@ def main() -> CInt | CExport:
k5: str = stdlib.malloc(16)
stdio.sprintf(k5, "key5")
p5: t.CPtr = ht3[k5]
v5: int = *(int | t.CPtr)(p5)
v5: int = *(int*)(p5)
stdio.printf("ht3[key5]=%d\n", v5)
testcheck.check(v5 == 500, "ht expand key5 OK", "ht expand key5 FAILED")
k25: str = stdlib.malloc(16)
stdio.sprintf(k25, "key25")
p25: t.CPtr = ht3[k25]
v25: int = *(int | t.CPtr)(p25)
v25: int = *(int*)(p25)
stdio.printf("ht3[key25]=%d\n", v25)
testcheck.check(v25 == 2500, "ht expand key25 OK", "ht expand key25 FAILED")
k49: str = stdlib.malloc(16)
stdio.sprintf(k49, "key49")
p49: t.CPtr = ht3[k49]
v49: int = *(int | t.CPtr)(p49)
v49: int = *(int*)(p49)
stdio.printf("ht3[key49]=%d\n", v49)
testcheck.check(v49 == 4900, "ht expand key49 OK", "ht expand key49 FAILED")
@@ -169,12 +167,10 @@ def main() -> CInt | CExport:
# === Test 11: 删除后扩容 ===
testcheck.section("Test 11: 批量删除后操作")
j: int = 0
while j < 25:
for j in range(25):
del_buf: str = stdlib.malloc(16)
stdio.sprintf(del_buf, "key%d", j)
del ht3[del_buf]
j += 1
n3b: sizet = len(ht3)
stdio.printf("ht3 len=%lu (after 25 deletes)\n", n3b)
testcheck.check(n3b == 25, "ht after del OK (25)", "ht after del FAILED")
@@ -183,7 +179,7 @@ def main() -> CInt | CExport:
k30: str = stdlib.malloc(16)
stdio.sprintf(k30, "key30")
p30: t.CPtr = ht3[k30]
v30: int = *(int | t.CPtr)(p30)
v30: int = *(int*)(p30)
stdio.printf("ht3[key30]=%d\n", v30)
testcheck.check(v30 == 3000, "ht key30 after del OK", "ht key30 after del FAILED")
+5 -5
View File
@@ -5,7 +5,7 @@ import testcheck
def test_for_in_string():
testcheck.section("Test 1: for-in string iteration")
s: char | t.CPtr = "Hello"
s: char* = "Hello"
result: int = 0
for ch in s:
result += ch
@@ -14,7 +14,7 @@ def test_for_in_string():
def test_for_in_char_ptr():
testcheck.section("Test 2: for-in char* iteration")
s: char | t.CPtr = "ABC"
s: char* = "ABC"
chars: t.CArray[int, 4] = [0]
idx: int = 0
for ch in s:
@@ -25,16 +25,16 @@ def test_for_in_char_ptr():
def test_strcpy_for_in():
testcheck.section("Test 3: strcpy using for-in")
src: char | t.CPtr = "test"
src: char* = "test"
# 手动实现 strcpy 用 for-in
import w32.win32memory
buf: char | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 12288, 4)
buf: char* = w32.win32memory.VirtualAlloc(None, 64, 12288, 4)
if uint64(buf) == 0:
stdio.printf("SKIP: VirtualAlloc returned NULL\n")
return
string.memset(buf, 0, 64)
# 用 for-in 复制
p: char | t.CPtr = buf
p: char* = buf
for ch in src:
p[0] = ch
p += 1
+64 -64
View File
@@ -10,46 +10,46 @@ import testcheck
# ============================================================
# 测试 1:构造 JSON 值(使用 mpool)
# ============================================================
def test_construct(pool: memhub.MemPool | t.CPtr):
def test_construct(pool: memhub.MemPool*):
testcheck.section("Construct JsonValue (with mpool)")
# null
v1: json.JsonValue | t.CPtr = json.null(pool)
v1: json.JsonValue* = json.null(pool)
testcheck.check(v1.is_null(), "null is_null", "null is_null")
# bool
v2: json.JsonValue | t.CPtr = json.bool_val(pool, True)
v2: json.JsonValue* = json.bool_val(pool, True)
testcheck.check(v2.is_bool(), "bool true is_bool", "bool true is_bool")
testcheck.check(v2.as_bool(), "bool true as_bool", "bool true as_bool")
v3: json.JsonValue | t.CPtr = json.bool_val(pool, False)
v3: json.JsonValue* = json.bool_val(pool, False)
testcheck.check(not v3.as_bool(), "bool false !as_bool", "bool false !as_bool")
# int
v4: json.JsonValue | t.CPtr = json.int_val(pool, 42)
v4: json.JsonValue* = json.int_val(pool, 42)
testcheck.check(v4.is_int(), "int is_int", "int is_int")
testcheck.check(v4.as_int() == 42, "int 42 == 42", "int 42 == 42")
v5: json.JsonValue | t.CPtr = json.int_val(pool, -100)
v5: json.JsonValue* = json.int_val(pool, -100)
testcheck.check(v5.as_int() == -100, "int -100 == -100", "int -100 == -100")
# float
v6: json.JsonValue | t.CPtr = json.float_val(pool, 3.14)
v6: json.JsonValue* = json.float_val(pool, 3.14)
testcheck.check(v6.is_float(), "float is_float", "float is_float")
testcheck.check(v6.as_float() > 3.13 and v6.as_float() < 3.15, "float 3.14 ~= 3.14", "float 3.14 ~= 3.14")
# string
v7: json.JsonValue | t.CPtr = json.string_val(pool, "hello")
v7: json.JsonValue* = json.string_val(pool, "hello")
testcheck.check(v7.is_string(), "string is_string", "string is_string")
testcheck.check(string.strcmp(v7.as_string(), "hello") == 0, "string == hello", "string == hello")
# array
v8: json.JsonValue | t.CPtr = json.array(pool)
v8: json.JsonValue* = json.array(pool)
testcheck.check(v8.is_array(), "array is_array", "array is_array")
testcheck.check(len(v8) == 0, "array empty len()==0", "array empty len()==0")
# object
v9: json.JsonValue | t.CPtr = json.object(pool)
v9: json.JsonValue* = json.object(pool)
testcheck.check(v9.is_object(), "object is_object", "object is_object")
testcheck.check(len(v9) == 0, "object empty len()==0", "object empty len()==0")
@@ -57,11 +57,11 @@ def test_construct(pool: memhub.MemPool | t.CPtr):
# ============================================================
# 测试 2:构造数组和对象(Python风格API)
# ============================================================
def test_build_structures(pool: memhub.MemPool | t.CPtr):
def test_build_structures(pool: memhub.MemPool*):
testcheck.section("Build Arrays and Objects (Pythonic API)")
# 构建数组 [1, 2, 3]
arr: json.JsonValue | t.CPtr = json.array(pool)
arr: json.JsonValue* = json.array(pool)
json.array_append(pool, arr, json.int_val(pool, 1))
json.array_append(pool, arr, json.int_val(pool, 2))
json.array_append(pool, arr, json.int_val(pool, 3))
@@ -71,152 +71,152 @@ def test_build_structures(pool: memhub.MemPool | t.CPtr):
testcheck.check(arr.get_item(2).as_int() == 3, "array get_item(2)==3", "array get_item(2)==3")
# 构建对象 {"name": "Viper", "version": 1}
obj: json.JsonValue | t.CPtr = json.object(pool)
obj: json.JsonValue* = json.object(pool)
json.object_set(pool, obj, "name", json.string_val(pool, "Viper"))
json.object_set(pool, obj, "version", json.int_val(pool, 1))
testcheck.check(len(obj) == 2, "object len()==2", "object len()==2")
# Python风格取值:obj["key"]
name_val: json.JsonValue | t.CPtr = obj["name"]
name_val: json.JsonValue* = obj["name"]
testcheck.check(name_val != None and string.strcmp(name_val.as_string(), "Viper") == 0, "obj['name']==Viper", "obj['name']==Viper")
ver_val: json.JsonValue | t.CPtr = obj["version"]
ver_val: json.JsonValue* = obj["version"]
testcheck.check(ver_val != None and ver_val.as_int() == 1, "obj['version']==1", "obj['version']==1")
missing: json.JsonValue | t.CPtr = obj["missing"]
missing: json.JsonValue* = obj["missing"]
testcheck.check(missing == None, "obj['missing']==None", "obj['missing']==None")
# ============================================================
# 测试 3:JSON 解析
# ============================================================
def test_parse(pool: memhub.MemPool | t.CPtr):
def test_parse(pool: memhub.MemPool*):
testcheck.section("Parse JSON")
# 解析整数
v1: json.JsonValue | t.CPtr = json.parse(pool, "42")
v1: json.JsonValue* = json.parse(pool, "42")
testcheck.check(v1.is_int(), "parse int is_int", "parse int is_int")
testcheck.check(v1.as_int() == 42, "parse int == 42", "parse int == 42")
# 解析负数
v2: json.JsonValue | t.CPtr = json.parse(pool, "-7")
v2: json.JsonValue* = json.parse(pool, "-7")
testcheck.check(v2.as_int() == -7, "parse neg int == -7", "parse neg int == -7")
# 解析浮点数
v3: json.JsonValue | t.CPtr = json.parse(pool, "3.14")
v3: json.JsonValue* = json.parse(pool, "3.14")
testcheck.check(v3.is_float(), "parse float is_float", "parse float is_float")
testcheck.check(v3.as_float() > 3.13 and v3.as_float() < 3.15, "parse float ~= 3.14", "parse float ~= 3.14")
# 解析字符串
v4: json.JsonValue | t.CPtr = json.parse(pool, '"hello world"')
v4: json.JsonValue* = json.parse(pool, '"hello world"')
testcheck.check(v4.is_string(), "parse string is_string", "parse string is_string")
testcheck.check(string.strcmp(v4.as_string(), "hello world") == 0, "parse string == hello world", "parse string == hello world")
# 解析布尔
v5: json.JsonValue | t.CPtr = json.parse(pool, "true")
v5: json.JsonValue* = json.parse(pool, "true")
testcheck.check(v5.is_bool(), "parse true is_bool", "parse true is_bool")
testcheck.check(v5.as_bool(), "parse true as_bool", "parse true as_bool")
v6: json.JsonValue | t.CPtr = json.parse(pool, "false")
v6: json.JsonValue* = json.parse(pool, "false")
testcheck.check(not v6.as_bool(), "parse false !as_bool", "parse false !as_bool")
# 解析 null
v7: json.JsonValue | t.CPtr = json.parse(pool, "null")
v7: json.JsonValue* = json.parse(pool, "null")
testcheck.check(v7.is_null(), "parse null is_null", "parse null is_null")
# 解析数组
v8: json.JsonValue | t.CPtr = json.parse(pool, "[1, 2, 3]")
v8: json.JsonValue* = json.parse(pool, "[1, 2, 3]")
testcheck.check(v8.is_array(), "parse array is_array", "parse array is_array")
testcheck.check(len(v8) == 3, "parse array len()==3", "parse array len()==3")
testcheck.check(v8.get_item(0).as_int() == 1, "parse array get_item(0)==1", "parse array get_item(0)==1")
testcheck.check(v8.get_item(2).as_int() == 3, "parse array get_item(2)==3", "parse array get_item(2)==3")
# 解析对象(Python风格取值)
v9: json.JsonValue | t.CPtr = json.parse(pool, '{"x": 10, "y": 20}')
v9: json.JsonValue* = json.parse(pool, '{"x": 10, "y": 20}')
testcheck.check(v9.is_object(), "parse object is_object", "parse object is_object")
testcheck.check(len(v9) == 2, "parse object len()==2", "parse object len()==2")
x_val: json.JsonValue | t.CPtr = v9["x"]
x_val: json.JsonValue* = v9["x"]
testcheck.check(x_val != None and x_val.as_int() == 10, "parse obj['x']==10", "parse obj['x']==10")
y_val: json.JsonValue | t.CPtr = v9["y"]
y_val: json.JsonValue* = v9["y"]
testcheck.check(y_val != None and y_val.as_int() == 20, "parse obj['y']==20", "parse obj['y']==20")
# ============================================================
# 测试 4:JSON 序列化
# ============================================================
def test_write(pool: memhub.MemPool | t.CPtr):
def test_write(pool: memhub.MemPool*):
testcheck.section("Write JSON")
# 写整数
v1: json.JsonValue | t.CPtr = json.int_val(pool, 42)
s1: char | t.CPtr = json.write(pool, v1, False)
v1: json.JsonValue* = json.int_val(pool, 42)
s1: char* = json.write(pool, v1, False)
testcheck.check(string.strcmp(s1, "42") == 0, "write int 42", "write int 42")
# 写字符串
v2: json.JsonValue | t.CPtr = json.string_val(pool, "hello")
s2: char | t.CPtr = json.write(pool, v2, False)
v2: json.JsonValue* = json.string_val(pool, "hello")
s2: char* = json.write(pool, v2, False)
testcheck.check(string.strcmp(s2, '"hello"') == 0, "write string hello", "write string hello")
# 写布尔
v3: json.JsonValue | t.CPtr = json.bool_val(pool, True)
s3: char | t.CPtr = json.write(pool, v3, False)
v3: json.JsonValue* = json.bool_val(pool, True)
s3: char* = json.write(pool, v3, False)
testcheck.check(string.strcmp(s3, "true") == 0, "write bool true", "write bool true")
v4: json.JsonValue | t.CPtr = json.bool_val(pool, False)
s4: char | t.CPtr = json.write(pool, v4, False)
v4: json.JsonValue* = json.bool_val(pool, False)
s4: char* = json.write(pool, v4, False)
testcheck.check(string.strcmp(s4, "false") == 0, "write bool false", "write bool false")
# 写 null
v5: json.JsonValue | t.CPtr = json.null(pool)
s5: char | t.CPtr = json.write(pool, v5, False)
v5: json.JsonValue* = json.null(pool)
s5: char* = json.write(pool, v5, False)
testcheck.check(string.strcmp(s5, "null") == 0, "write null", "write null")
# 写数组
arr: json.JsonValue | t.CPtr = json.array(pool)
arr: json.JsonValue* = json.array(pool)
json.array_append(pool, arr, json.int_val(pool, 1))
json.array_append(pool, arr, json.int_val(pool, 2))
json.array_append(pool, arr, json.int_val(pool, 3))
s6: char | t.CPtr = json.write(pool, arr, False)
s6: char* = json.write(pool, arr, False)
testcheck.check(string.strcmp(s6, "[1,2,3]") == 0, "write array [1,2,3]", "write array [1,2,3]")
# 写对象
obj: json.JsonValue | t.CPtr = json.object(pool)
obj: json.JsonValue* = json.object(pool)
json.object_set(pool, obj, "a", json.int_val(pool, 1))
json.object_set(pool, obj, "b", json.string_val(pool, "x"))
s7: char | t.CPtr = json.write(pool, obj, False)
s7: char* = json.write(pool, obj, False)
testcheck.check(s7 != None, "write object non-null", "write object non-null")
# ============================================================
# 测试 5:解析复杂嵌套 JSON(Python风格API)
# ============================================================
def test_nested(pool: memhub.MemPool | t.CPtr):
def test_nested(pool: memhub.MemPool*):
testcheck.section("Parse Nested JSON (Pythonic API)")
src: char | t.CPtr = '{"name": "Viper", "version": 1, "features": ["fast", "safe", "portable"], "nested": {"key": "value", "num": 99}}'
root: json.JsonValue | t.CPtr = json.parse(pool, src)
src: char* = '{"name": "Viper", "version": 1, "features": ["fast", "safe", "portable"], "nested": {"key": "value", "num": 99}}'
root: json.JsonValue* = json.parse(pool, src)
testcheck.check(root.is_object(), "nested is_object", "nested is_object")
testcheck.check(len(root) == 4, "nested len()==4", "nested len()==4")
# Python风格取值:root["name"]
name: json.JsonValue | t.CPtr = root["name"]
name: json.JsonValue* = root["name"]
testcheck.check(name != None and string.strcmp(name.as_string(), "Viper") == 0, "root['name']==Viper", "root['name']==Viper")
# root["version"]
ver: json.JsonValue | t.CPtr = root["version"]
ver: json.JsonValue* = root["version"]
testcheck.check(ver != None and ver.as_int() == 1, "root['version']==1", "root['version']==1")
# root["features"] 数组
feat: json.JsonValue | t.CPtr = root["features"]
feat: json.JsonValue* = root["features"]
testcheck.check(feat != None and feat.is_array(), "root['features'] is_array", "root['features'] is_array")
testcheck.check(feat != None and len(feat) == 3, "root['features'] len()==3", "root['features'] len()==3")
testcheck.check(feat != None and string.strcmp(feat.get_item(0).as_string(), "fast") == 0, "root['features'][0]==fast", "root['features'][0]==fast")
testcheck.check(feat != None and string.strcmp(feat.get_item(2).as_string(), "portable") == 0, "root['features'][2]==portable", "root['features'][2]==portable")
# root["nested"] 对象
nested: json.JsonValue | t.CPtr = root["nested"]
nested: json.JsonValue* = root["nested"]
testcheck.check(nested != None and nested.is_object(), "root['nested'] is_object", "root['nested'] is_object")
nk: json.JsonValue | t.CPtr = nested["key"] if nested != None else None
nk: json.JsonValue* = nested["key"] if nested != None else None
testcheck.check(nk != None and string.strcmp(nk.as_string(), "value") == 0, "root['nested']['key']==value", "root['nested']['key']==value")
nn: json.JsonValue | t.CPtr = nested["num"] if nested != None else None
nn: json.JsonValue* = nested["num"] if nested != None else None
testcheck.check(nn != None and nn.as_int() == 99, "root['nested']['num']==99", "root['nested']['num']==99")
@@ -230,24 +230,24 @@ def test_mpool_reuse():
mem: t.CPtr = win32mem.VirtualAlloc(None, 8192, 0x3000, 0x04)
testcheck.check(mem != None, "VirtualAlloc ok", "VirtualAlloc ok")
pool: memhub.MemPool | t.CPtr = memhub.MemPool(mem, 8192)
pool: memhub.MemPool* = memhub.MemPool(mem, 8192)
# 第一次使用
v1: json.JsonValue | t.CPtr = json.int_val(pool, 100)
v1: json.JsonValue* = json.int_val(pool, 100)
testcheck.check(v1.as_int() == 100, "reuse round1 int==100", "reuse round1 int==100")
# 重置 mpool
pool.reset()
# 第二次使用(内存复用)
v2: json.JsonValue | t.CPtr = json.string_val(pool, "reused")
v2: json.JsonValue* = json.string_val(pool, "reused")
testcheck.check(string.strcmp(v2.as_string(), "reused") == 0, "reuse round2 string==reused", "reuse round2 string==reused")
# 重置后再解析
pool.reset()
v3: json.JsonValue | t.CPtr = json.parse(pool, '{"test": true}')
v3: json.JsonValue* = json.parse(pool, '{"test": true}')
testcheck.check(v3.is_object(), "reuse round3 parse ok", "reuse round3 parse ok")
tv: json.JsonValue | t.CPtr = v3["test"]
tv: json.JsonValue* = v3["test"]
testcheck.check(tv != None and tv.as_bool(), "reuse round3 obj['test']==true", "reuse round3 obj['test']==true")
win32mem.VirtualFree(mem, 0, 0x8000)
@@ -256,21 +256,21 @@ def test_mpool_reuse():
# ============================================================
# 测试 7:转义字符解析
# ============================================================
def test_escape(pool: memhub.MemPool | t.CPtr):
def test_escape(pool: memhub.MemPool*):
testcheck.section("Escape Characters")
# 解析含转义字符的字符串
v1: json.JsonValue | t.CPtr = json.parse(pool, '"hello\\nworld"')
v1: json.JsonValue* = json.parse(pool, '"hello\\nworld"')
testcheck.check(v1.is_string(), "escape \\n is_string", "escape \\n is_string")
sv1: char | t.CPtr = v1.as_string()
sv1: char* = v1.as_string()
testcheck.check(sv1 != None and sv1[5] == '\n', "escape \\n contains newline", "escape \\n contains newline")
v2: json.JsonValue | t.CPtr = json.parse(pool, '"tab\\there"')
v2: json.JsonValue* = json.parse(pool, '"tab\\there"')
testcheck.check(v2.is_string(), "escape \\t is_string", "escape \\t is_string")
sv2: char | t.CPtr = v2.as_string()
sv2: char* = v2.as_string()
testcheck.check(sv2 != None and sv2[3] == '\t', "escape \\t contains tab", "escape \\t contains tab")
v3: json.JsonValue | t.CPtr = json.parse(pool, '"quote\\""')
v3: json.JsonValue* = json.parse(pool, '"quote\\""')
testcheck.check(v3.is_string(), "escape \\\" is_string", "escape \\\" is_string")
@@ -282,7 +282,7 @@ def main() -> int | t.CExport:
# 使用 mpool 的 bump 分配器
mem: t.CPtr = win32mem.VirtualAlloc(None, 65536, 0x3000, 0x04)
pool: memhub.MemPool | t.CPtr = memhub.MemPool(mem, 65536)
pool: memhub.MemPool* = memhub.MemPool(mem, 65536)
test_construct(pool)
pool.reset()
+1 -1
View File
@@ -16,7 +16,7 @@ def main() -> CInt | CExport:
# 创建 mbuddy arena
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
# === Test 1: 创建和 append ===
testcheck.section("Test 1: 创建和 append")
+6 -18
View File
@@ -65,8 +65,7 @@ def ForWithElifBranchTest(value: int):
def WhileWithIfElifElseTest(iterations: int):
counter: int = 0
while counter < iterations:
for counter in range(iterations):
if counter < 2:
print("Phase 1: ", counter)
elif counter < 4:
@@ -75,7 +74,6 @@ def WhileWithIfElifElseTest(iterations: int):
print("Phase 3: ", counter)
else:
print("Phase 4: ", counter)
counter += 1
print("While done")
@@ -136,8 +134,7 @@ def ComplexForWhileMatchTest(outer_limit: int, inner_limit: int):
j: int = 0
result: int = 0
for i in range(outer_limit):
j = 0
while j < inner_limit:
for j in range(inner_limit):
match (i, j):
case (0, 0):
result += 1
@@ -149,7 +146,6 @@ def ComplexForWhileMatchTest(outer_limit: int, inner_limit: int):
result += 1000
case _:
result += 10000
j += 1
print("Complex match result: ", result)
@@ -186,19 +182,15 @@ def WhileWithBreakConditionTest(limit: int):
def NestedWhileWithMultipleBreakPoints(depth: int, width: int):
d: int = 0
w: int = 0
count: int = 0
while d < depth:
w = 0
while w < width:
for d in range(depth):
for w in range(width):
if w == 2:
break
if d == 1 and w == 1:
c.Break
count += 1
w += 1
d += 1
print("Nested break count: ", count)
@@ -221,9 +213,8 @@ def ForWithMatchCaseInLoopTest(iterations: int):
def ComplexLogicWithElifChains(a: int, b: int, c_val: int):
i: int = 0
result: int = 0
while i < 10:
for i in range(10):
if i < a:
if i < b:
result += 1
@@ -240,7 +231,6 @@ def ComplexLogicWithElifChains(a: int, b: int, c_val: int):
result += 6
else:
result += 7
i += 1
print("Complex elif chain result: ", result)
@@ -331,9 +321,8 @@ def ComplexCaseMatchingWithRanges(start: int, end: int):
def WhileWithElifInElifChain(limit: int):
i: int = 0
result: int = 0
while i < limit:
for i in range(limit):
if i < 2:
if i == 0:
result = 1
@@ -352,7 +341,6 @@ def WhileWithElifInElifChain(limit: int):
else:
result = 7
print("Chain result[", i, "]: ", result)
i += 1
def ForWithCaseNoBreakNested(inner_limit: int):
+7 -21
View File
@@ -78,17 +78,13 @@ def WhileWithElifElseTest(start: int, end: int):
def NestedWhileWithMacrosTest(outer_limit: int, inner_limit: int):
outer: int = 0
inner: int = 0
total_ops: int = 0
while outer < outer_limit:
inner = 0
while inner < inner_limit:
for outer in range(outer_limit):
for inner in range(inner_limit):
if inner == config.TRUE:
print("Inner loop break condition at: ", inner)
total_ops += 1
inner += 1
outer += 1
print("Total operations: ", total_ops)
@@ -114,9 +110,8 @@ def ComplexConditionTest(a: int, b: int, c_val: int):
def RetryLoopTest(retry_count: int) -> int:
attempt: int = 0
success: int = 0
while attempt < retry_count:
for attempt in range(retry_count):
if attempt < config.MAX_RETRY:
print("Attempt: ", attempt, " less than max")
success = attempt * 2
@@ -126,7 +121,6 @@ def RetryLoopTest(retry_count: int) -> int:
else:
print("Beyond max retry")
success = -2
attempt += 1
return success
@@ -189,10 +183,8 @@ def CompoundAssignmentMathTest(a: int, b: int) -> int:
def PowerAndModuloTest(base: int, exponent: int) -> int:
result: int = 1
temp: int = 0
i: int = 0
while i < exponent:
for i in range(exponent):
result *= base
i += 1
print("Power: ", result)
temp = result % config.MODULO_DIVISOR
print("Power mod: ", temp)
@@ -226,17 +218,15 @@ def MixedArithmeticTest(x: int, y: int, z: int) -> int:
def MathWithWhileLoopTest(start: int, count: int) -> int:
idx: int = 0
accumulator: int = 0
multiplier: int = config.MATH_SCALE
while idx < count:
for idx in range(count):
temp: int = (start + idx) * multiplier
temp = temp + config.MATH_OFFSET
if temp > config.THRESHOLD:
temp = config.THRESHOLD
accumulator += temp
multiplier += 1
idx += 1
print("Accumulator: ", accumulator)
return accumulator
@@ -245,12 +235,10 @@ def ComplexNestedMathTest(a: int, b: int) -> int:
layer1: int = 0
layer2: int = 0
layer3: int = 0
i: int = 0
layer1 = (a + b) * config.MATH_SCALE
print("Layer1: ", layer1)
while i < config.BIT_RANGE:
for i in range(config.BIT_RANGE):
layer2 += layer1 >> 1
i += 1
print("Layer2: ", layer2)
layer3 = layer1 + layer2 - config.MATH_OFFSET
print("Layer3: ", layer3)
@@ -261,8 +249,7 @@ def ComplexNestedMathTest(a: int, b: int) -> int:
def ConditionalMathChainTest(value: int) -> int:
result: int = 0
step: int = 0
while step < config.LOOP_LIMIT:
for step in range(config.LOOP_LIMIT):
if step < 5:
result += step * config.MATH_SCALE
print("step<5: ", result)
@@ -275,7 +262,6 @@ def ConditionalMathChainTest(value: int) -> int:
else:
result = result * config.EXPONENT_BASE % config.MODULO_DIVISOR
print("step>=15: ", result)
step += 1
return result
+2 -2
View File
@@ -7,7 +7,7 @@ import memhub
# 多态测试: 通过 MemManager 基类指针调用, 验证 vtable 分派到正确子类
def test_polymorphic(mgr: memhub.MemManager | t.CPtr, size: sizet) -> int:
def test_polymorphic(mgr: memhub.MemManager*, size: sizet) -> int:
p: t.CPtr = mgr.alloc(size)
if p is None:
return 0
@@ -16,7 +16,7 @@ def test_polymorphic(mgr: memhub.MemManager | t.CPtr, size: sizet) -> int:
# 测试 calloc 多态: calloc 是 MemManager 具体方法, 内部调 self.alloc (虚函数)
def test_calloc_polymorphic(mgr: memhub.MemManager | t.CPtr) -> int:
def test_calloc_polymorphic(mgr: memhub.MemManager*) -> int:
p: t.CPtr = mgr.calloc(4, 8)
if p is None:
return 0
+2 -2
View File
@@ -97,9 +97,9 @@ def test_multilevel_chain():
# DataMixin.get_val 内 self.val 需 this_adjust 到第二父类字段区。
# ============================================================
novirtual class PtrMixin:
name: char | t.CPtr
name: char*
def get_name(self) -> char | t.CPtr:
def get_name(self) -> char*:
return self.name
+39 -39
View File
@@ -36,9 +36,9 @@ def test_append():
"append count=3",
"append count fail")
# 验证顺序(LinkedNode* → Node* 显式向下转型)
c1: Node | t.CPtr = (Node | t.CPtr)(root.child)
c2: Node | t.CPtr = (Node | t.CPtr)(c1.next)
c3: Node | t.CPtr = (Node | t.CPtr)(c2.next)
c1: Node* = (Node*)(root.child)
c2: Node* = (Node*)(c1.next)
c3: Node* = (Node*)(c2.next)
testcheck.check(c1.value == 10 and c2.value == 20 and c3.value == 30,
"order 10,20,30",
"order fail")
@@ -57,7 +57,7 @@ def test_prev_link():
root.append(a)
root.append(b)
# b.prev 应指向 a
bp: Node | t.CPtr = (Node | t.CPtr)(b.prev)
bp: Node* = (Node*)(b.prev)
testcheck.check(bp is not None and bp.value == 1,
"b.prev.value=1",
"prev link fail")
@@ -78,12 +78,12 @@ def test_last_child():
a.value = 100
b.value = 200
root.append(a)
lc: Node | t.CPtr = (Node | t.CPtr)(root.last_child)
lc: Node* = (Node*)(root.last_child)
testcheck.check(lc is not None and lc.value == 100,
"last_child=100 after 1 append",
"last_child fail 1")
root.append(b)
lc = (Node | t.CPtr)(root.last_child)
lc = (Node*)(root.last_child)
testcheck.check(lc is not None and lc.value == 200,
"last_child=200 after 2 append",
"last_child fail 2")
@@ -110,12 +110,12 @@ def test_remove():
"count=2 after detach",
"detach count fail")
# a.next 应直接指向 c
an: Node | t.CPtr = (Node | t.CPtr)(a.next)
an: Node* = (Node*)(a.next)
testcheck.check(an is not None and an.value == 3,
"a.next.value=3",
"detach link fail")
# c.prev 应指向 a
cp: Node | t.CPtr = (Node | t.CPtr)(c.prev)
cp: Node* = (Node*)(c.prev)
testcheck.check(cp is not None and cp.value == 1,
"c.prev.value=1",
"detach prev fail")
@@ -141,7 +141,7 @@ def test_remove_child():
testcheck.check(root.child_count == 1,
"count=1 after remove_child",
"remove_child count fail")
fc: Node | t.CPtr = (Node | t.CPtr)(root.child)
fc: Node* = (Node*)(root.child)
testcheck.check(fc is not None and fc.value == 20,
"first child=20",
"remove_child first fail")
@@ -166,13 +166,13 @@ def test_insert_ops():
root.insert_before(c, b) # [1, 2, 3] 在 c 前插入 b
root.insert_after(a, d) # [1, 4, 2, 3] 在 a 后插入 d
# 遍历验证顺序
cur: Node | t.CPtr = (Node | t.CPtr)(root.child)
cur: Node* = (Node*)(root.child)
v0: int = cur.value
cur = (Node | t.CPtr)(cur.next)
cur = (Node*)(cur.next)
v1: int = cur.value
cur = (Node | t.CPtr)(cur.next)
cur = (Node*)(cur.next)
v2: int = cur.value
cur = (Node | t.CPtr)(cur.next)
cur = (Node*)(cur.next)
v3: int = cur.value
testcheck.check(v0 == 1 and v1 == 4 and v2 == 2 and v3 == 3,
"order 1,4,2,3",
@@ -206,10 +206,10 @@ def test_index_access():
root.append(n3)
root.append(n4)
# child_at
r0: Node | t.CPtr = (Node | t.CPtr)(root.child_at(0))
r2: Node | t.CPtr = (Node | t.CPtr)(root.child_at(2))
r4: Node | t.CPtr = (Node | t.CPtr)(root.child_at(4))
r5: Node | t.CPtr = (Node | t.CPtr)(root.child_at(5))
r0: Node* = (Node*)(root.child_at(0))
r2: Node* = (Node*)(root.child_at(2))
r4: Node* = (Node*)(root.child_at(4))
r5: Node* = (Node*)(root.child_at(5))
testcheck.check(r0 is not None and r0.value == 0,
"child_at(0)=0",
"child_at 0 fail")
@@ -251,8 +251,8 @@ def test_sibling_traverse():
"has_children=1",
"has_children fail")
# 从 b 出发找头尾兄弟
fs: Node | t.CPtr = (Node | t.CPtr)(b.first_sibling())
ls: Node | t.CPtr = (Node | t.CPtr)(b.last_sibling())
fs: Node* = (Node*)(b.first_sibling())
ls: Node* = (Node*)(b.last_sibling())
testcheck.check(fs is not None and fs.value == 1,
"first_sibling=1",
"first_sibling fail")
@@ -303,7 +303,7 @@ def test_slist():
n1.value = 200
n2.value = 300
# append (O(n)) — 直接用 n0 作为 head
head: linkedlist.SListNode | t.CPtr = n0
head: linkedlist.SListNode* = n0
head = head.append(n1)
head = head.append(n2)
# count
@@ -311,10 +311,10 @@ def test_slist():
"count=3",
"count fail")
# at
a0: SNode | t.CPtr = (SNode | t.CPtr)(head.at(0))
a1: SNode | t.CPtr = (SNode | t.CPtr)(head.at(1))
a2: SNode | t.CPtr = (SNode | t.CPtr)(head.at(2))
a3: SNode | t.CPtr = (SNode | t.CPtr)(head.at(3))
a0: SNode* = (SNode*)(head.at(0))
a1: SNode* = (SNode*)(head.at(1))
a2: SNode* = (SNode*)(head.at(2))
a3: SNode* = (SNode*)(head.at(3))
testcheck.check(a0 is not None and a0.value == 100,
"at(0)=100",
"at 0 fail")
@@ -336,14 +336,14 @@ def test_slist():
"n1.Next cleared",
"n1.Next not cleared")
# 移除后 a0.Next 应指向 n2
a0b: SNode | t.CPtr = (SNode | t.CPtr)(a0.Next)
a0b: SNode* = (SNode*)(a0.Next)
testcheck.check(a0b is not None and a0b.value == 300,
"after remove a0.Next=300",
"a0.Next fail")
# append_after (O(1))
n3: SNode = SNode()
n3.value = 400
tail: linkedlist.SListNode | t.CPtr = n2.append_after(n3)
tail: linkedlist.SListNode* = n2.append_after(n3)
testcheck.check(tail is n3,
"append_after returns n3",
"append_after fail")
@@ -358,7 +358,7 @@ def test_slist():
def test_sprintf_vararg():
testcheck.section("Test 11: viperlib.sprintf *args forwarding")
# 测试 %d 单参数
buf: char | t.CPtr = stdlib.malloc(32)
buf: char* = stdlib.malloc(32)
if buf is None: return
buf[0] = 0
viperlib.sprintf(buf, "key%d", 42)
@@ -366,7 +366,7 @@ def test_sprintf_vararg():
"sprintf key42",
"sprintf key%d fail")
# 测试无参数
buf2: char | t.CPtr = stdlib.malloc(32)
buf2: char* = stdlib.malloc(32)
if buf2 is None: return
buf2[0] = 0
viperlib.sprintf(buf2, "hello")
@@ -374,7 +374,7 @@ def test_sprintf_vararg():
"sprintf hello",
"sprintf no-arg fail")
# 测试多参数
buf3: char | t.CPtr = stdlib.malloc(32)
buf3: char* = stdlib.malloc(32)
if buf3 is None: return
buf3[0] = 0
viperlib.sprintf(buf3, "%d+%d=%d", 1, 2, 3)
@@ -396,11 +396,11 @@ def test_sprintf_vararg():
# 注:编译器暂不支持 模块.泛型类[T]() 跨模块构造,故本地定义。
# ============================================================
novirtual class GSListNode[T]:
Next: T | t.CPtr
Next: T*
novirtual class GSList[T]:
Head: T | t.CPtr
Tail: T | t.CPtr
Head: T*
Tail: T*
Count: sizet
def __init__(self):
@@ -421,9 +421,9 @@ novirtual class GSList[T]:
def count(self) -> sizet:
return self.Count
def at(self, index: sizet) -> T | t.CPtr:
def at(self, index: sizet) -> T*:
if self.Head is None: return None
cur: T | t.CPtr = self.Head
cur: T* = self.Head
i: sizet = 0
while cur is not None:
if i == index: return cur
@@ -439,7 +439,7 @@ class GNode(GSListNode[GNode]):
def test_generic_slist():
testcheck.section("Test 12: Generic GSListNode[T] + GSList[T]")
# 技术点 3: 泛型类作字段类型 + 构造
lst: GSList[GNode] | t.CPtr = GSList[GNode]()
lst: GSList[GNode]* = GSList[GNode]()
# 技术点 1+2: 递归泛型 + NoVTable 组合(GNode 定义在上方)
n0: GNode = GNode()
@@ -460,10 +460,10 @@ def test_generic_slist():
"GSList count fail")
# at (O(n)) — 返回 GNode|CPtr,无需向下转型
a0: GNode | t.CPtr = lst.at(0)
a1: GNode | t.CPtr = lst.at(1)
a2: GNode | t.CPtr = lst.at(2)
a3: GNode | t.CPtr = lst.at(3)
a0: GNode* = lst.at(0)
a1: GNode* = lst.at(1)
a2: GNode* = lst.at(2)
a3: GNode* = lst.at(3)
testcheck.check(a0 is not None and a0.Value == 10,
"GSList.at(0)=10",
"GSList at 0 fail")
+142 -150
View File
@@ -18,8 +18,8 @@ SIMD_BLOCK: sizet = 4
# ============================================================
# Global state
# ============================================================
arena: uint8 | t.CPtr = None
pool: memhub.MemPool | t.CPtr = None
arena: uint8* = None
pool: memhub.MemPool* = None
test_passed: int = 0
test_failed: int = 0
@@ -78,18 +78,18 @@ def timer_sec() -> double:
# ============================================================
# Utility: quick array creation
# ============================================================
def vec4(p: memhub.MemPool | t.CPtr, v0: double, v1: double, v2: double, v3: double) -> numpy.ndarray[double] | t.CPtr:
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(p, 4)
def vec4(p: memhub.MemPool*, v0: double, v1: double, v2: double, v3: double) -> numpy.ndarray[double]*:
a: numpy.ndarray[double]* = numpy.zeros(p, 4)
a.data[0] = v0; a.data[1] = v1; a.data[2] = v2; a.data[3] = v3
return a
def vec3(p: memhub.MemPool | t.CPtr, v0: double, v1: double, v2: double) -> numpy.ndarray[double] | t.CPtr:
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(p, 3)
def vec3(p: memhub.MemPool*, v0: double, v1: double, v2: double) -> numpy.ndarray[double]*:
a: numpy.ndarray[double]* = numpy.zeros(p, 3)
a.data[0] = v0; a.data[1] = v1; a.data[2] = v2
return a
def vec2(p: memhub.MemPool | t.CPtr, v0: double, v1: double) -> numpy.ndarray[double] | t.CPtr:
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(p, 2)
def vec2(p: memhub.MemPool*, v0: double, v1: double) -> numpy.ndarray[double]*:
a: numpy.ndarray[double]* = numpy.zeros(p, 2)
a.data[0] = v0; a.data[1] = v1
return a
@@ -100,18 +100,18 @@ def vec2(p: memhub.MemPool | t.CPtr, v0: double, v1: double) -> numpy.ndarray[do
def test_zeros_ones():
section_header("zeros / ones / full")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 5)
a: numpy.ndarray[double]* = numpy.zeros(pool, 5)
check("zeros not None", a != None, "zeros returned None")
check("zeros size == 5", a.size == 5, "size mismatch")
check("zeros [0]==0", a.data[0] == double(0.0), "not zero")
check("zeros [4]==0", a.data[4] == double(0.0), "not zero")
b: numpy.ndarray[double] | t.CPtr = numpy.ones(pool, 4)
b: numpy.ndarray[double]* = numpy.ones(pool, 4)
check("ones not None", b != None, "ones returned None")
check("ones [0]==1", b.data[0] == double(1.0), "not one")
check("ones [3]==1", b.data[3] == double(1.0), "not one")
c: numpy.ndarray[double] | t.CPtr = numpy.full(pool, 3, double(7.5))
c: numpy.ndarray[double]* = numpy.full(pool, 3, double(7.5))
check("full not None", c != None, "full returned None")
check("full value", c.data[0] == double(7.5), "value mismatch")
@@ -124,13 +124,13 @@ def test_zeros_ones():
def test_arange_linspace():
section_header("arange / linspace")
a: numpy.ndarray[double] | t.CPtr = numpy.arange(pool, double(0.0), double(5.0), double(1.0))
a: numpy.ndarray[double]* = numpy.arange(pool, double(0.0), double(5.0), double(1.0))
check("arange not None", a != None, "arange returned None")
check("arange size == 5", a.size == 5, "size mismatch")
check("arange [0]==0", approx_eq(a.data[0], double(0.0)), "mismatch")
check("arange [4]==4", approx_eq(a.data[4], double(4.0)), "mismatch")
b: numpy.ndarray[double] | t.CPtr = numpy.linspace(pool, double(0.0), double(1.0), 5)
b: numpy.ndarray[double]* = numpy.linspace(pool, double(0.0), double(1.0), 5)
check("linspace not None", b != None, "linspace returned None")
check("linspace size == 5", b.size == 5, "size mismatch")
check("linspace [0]==0", approx_eq(b.data[0], double(0.0)), "mismatch")
@@ -144,15 +144,15 @@ def test_arange_linspace():
def test_eye_diag():
section_header("eye / diag")
e: numpy.ndarray[double] | t.CPtr = numpy.eye(pool, 3)
e: numpy.ndarray[double]* = numpy.eye(pool, 3)
check("eye not None", e != None, "eye returned None")
check("eye ndim == 2", e.ndim == 2, "ndim mismatch")
check("eye [0,0]==1", e.at2d(0, 0) == double(1.0), "mismatch")
check("eye [0,1]==0", e.at2d(0, 1) == double(0.0), "mismatch")
check("eye [1,1]==1", e.at2d(1, 1) == double(1.0), "mismatch")
vals: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(2.0), double(3.0))
d: numpy.ndarray[double] | t.CPtr = numpy.diag(pool, vals)
vals: numpy.ndarray[double]* = vec3(pool, double(1.0), double(2.0), double(3.0))
d: numpy.ndarray[double]* = numpy.diag(pool, vals)
check("diag not None", d != None, "diag returned None")
check("diag [0,0]==1", d.at2d(0, 0) == double(1.0), "mismatch")
check("diag [1,1]==2", d.at2d(1, 1) == double(2.0), "mismatch")
@@ -170,7 +170,7 @@ def test_eye_diag():
def test_sum_mean_min_max():
section_header("sum / mean / min / max / argmax / argmin")
a: numpy.ndarray[double] | t.CPtr = numpy.arange(pool, double(1.0), double(6.0), double(1.0))
a: numpy.ndarray[double]* = numpy.arange(pool, double(1.0), double(6.0), double(1.0))
check("sum == 15", approx_eq(a.sum(), double(15.0)), "mismatch")
check("mean == 3", approx_eq(a.mean(), double(3.0)), "mismatch")
check("min == 1", approx_eq(a.min(), double(1.0)), "mismatch")
@@ -185,12 +185,12 @@ def test_sum_mean_min_max():
def test_fill_copy():
section_header("fill / copy")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 3)
a: numpy.ndarray[double]* = numpy.zeros(pool, 3)
a.fill(double(9.0))
check("fill [0]==9", a.data[0] == double(9.0), "mismatch")
check("fill [2]==9", a.data[2] == double(9.0), "mismatch")
b: numpy.ndarray[double] | t.CPtr = a.copy()
b: numpy.ndarray[double]* = a.copy()
check("copy not None", b != None, "copy returned None")
check("copy [0]==9", b.data[0] == double(9.0), "mismatch")
@@ -208,21 +208,21 @@ def test_fill_copy():
def test_add_sub_mul_div():
section_header("__add__ / __sub__ / __mul__ / __truediv__")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(2.0), double(3.0))
b: numpy.ndarray[double] | t.CPtr = vec3(pool, double(4.0), double(5.0), double(6.0))
a: numpy.ndarray[double]* = vec3(pool, double(1.0), double(2.0), double(3.0))
b: numpy.ndarray[double]* = vec3(pool, double(4.0), double(5.0), double(6.0))
c_add: numpy.ndarray[double] | t.CPtr = a + b
c_add: numpy.ndarray[double]* = a + b
check("a+b not None", c_add != None, "add returned None")
check("a+b [0]==5", c_add.data[0] == double(5.0), "mismatch")
check("a+b [2]==9", c_add.data[2] == double(9.0), "mismatch")
c_sub: numpy.ndarray[double] | t.CPtr = a - b
c_sub: numpy.ndarray[double]* = a - b
check("a-b [0]==-3", c_sub.data[0] == double(-3.0), "mismatch")
c_mul: numpy.ndarray[double] | t.CPtr = a * b
c_mul: numpy.ndarray[double]* = a * b
check("a*b [1]==10", c_mul.data[1] == double(10.0), "mismatch")
c_div: numpy.ndarray[double] | t.CPtr = b / a
c_div: numpy.ndarray[double]* = b / a
check("b/a [0]==4", c_div.data[0] == double(4.0), "mismatch")
check("b/a [2]==2", c_div.data[2] == double(2.0), "mismatch")
@@ -238,8 +238,8 @@ def test_add_sub_mul_div():
def test_neg():
section_header("__neg__")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(-2.0), double(3.0))
neg_a: numpy.ndarray[double] | t.CPtr = -a
a: numpy.ndarray[double]* = vec3(pool, double(1.0), double(-2.0), double(3.0))
neg_a: numpy.ndarray[double]* = -a
check("neg not None", neg_a != None, "neg returned None")
check("neg [0]==-1", neg_a.data[0] == double(-1.0), "mismatch")
check("neg [1]==2", neg_a.data[1] == double(2.0), "mismatch")
@@ -252,7 +252,7 @@ def test_neg():
def test_len():
section_header("__len__")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 10)
a: numpy.ndarray[double]* = numpy.zeros(pool, 10)
check("len == 10", len(a) == 10, "mismatch")
a.delete()
@@ -265,18 +265,18 @@ def test_len():
def test_scalar_ops():
section_header("add_scalar / mul_scalar / sub_scalar / div_scalar")
a: numpy.ndarray[double] | t.CPtr = numpy.ones(pool, 3)
a: numpy.ndarray[double]* = numpy.ones(pool, 3)
r1: numpy.ndarray[double] | t.CPtr = numpy.add_scalar(a, double(2.0))
r1: numpy.ndarray[double]* = numpy.add_scalar(a, double(2.0))
check("add_scalar [0]==3", r1.data[0] == double(3.0), "mismatch")
r2: numpy.ndarray[double] | t.CPtr = numpy.mul_scalar(a, double(5.0))
r2: numpy.ndarray[double]* = numpy.mul_scalar(a, double(5.0))
check("mul_scalar [0]==5", r2.data[0] == double(5.0), "mismatch")
r3: numpy.ndarray[double] | t.CPtr = numpy.sub_scalar(a, double(0.5))
r3: numpy.ndarray[double]* = numpy.sub_scalar(a, double(0.5))
check("sub_scalar [0]==0.5", r3.data[0] == double(0.5), "mismatch")
r4: numpy.ndarray[double] | t.CPtr = numpy.div_scalar(a, double(2.0))
r4: numpy.ndarray[double]* = numpy.div_scalar(a, double(2.0))
check("div_scalar [0]==0.5", r4.data[0] == double(0.5), "mismatch")
a.delete()
@@ -293,20 +293,20 @@ def test_scalar_ops():
def test_math_funcs():
section_header("np_abs / np_sqrt / np_pow")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(4.0), double(9.0))
a: numpy.ndarray[double]* = vec3(pool, double(1.0), double(4.0), double(9.0))
r_sqrt: numpy.ndarray[double] | t.CPtr = numpy.np_sqrt(a)
r_sqrt: numpy.ndarray[double]* = numpy.np_sqrt(a)
check("sqrt [0]==1", approx_eq(r_sqrt.data[0], double(1.0)), "mismatch")
check("sqrt [1]==2", approx_eq(r_sqrt.data[1], double(2.0)), "mismatch")
check("sqrt [2]==3", approx_eq(r_sqrt.data[2], double(3.0)), "mismatch")
b: numpy.ndarray[double] | t.CPtr = vec3(pool, double(-1.0), double(-4.0), double(9.0))
r_abs: numpy.ndarray[double] | t.CPtr = numpy.np_abs(b)
b: numpy.ndarray[double]* = vec3(pool, double(-1.0), double(-4.0), double(9.0))
r_abs: numpy.ndarray[double]* = numpy.np_abs(b)
check("abs [0]==1", approx_eq(r_abs.data[0], double(1.0)), "mismatch")
check("abs [1]==4", approx_eq(r_abs.data[1], double(4.0)), "mismatch")
c: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(2.0), double(3.0))
r_pow: numpy.ndarray[double] | t.CPtr = numpy.np_pow(c, double(2.0))
c: numpy.ndarray[double]* = vec3(pool, double(1.0), double(2.0), double(3.0))
r_pow: numpy.ndarray[double]* = numpy.np_pow(c, double(2.0))
check("pow [0]==1", approx_eq(r_pow.data[0], double(1.0)), "mismatch")
check("pow [1]==4", approx_eq(r_pow.data[1], double(4.0)), "mismatch")
check("pow [2]==9", approx_eq(r_pow.data[2], double(9.0)), "mismatch")
@@ -327,15 +327,15 @@ def test_matmul():
section_header("matmul")
# [1,2;3,4] x [5,6;7,8] = [19,22;43,50]
a: numpy.ndarray[double] | t.CPtr = numpy.empty2d(pool, 2, 2)
a: numpy.ndarray[double]* = numpy.empty2d(pool, 2, 2)
a.set2d(0, 0, double(1.0)); a.set2d(0, 1, double(2.0))
a.set2d(1, 0, double(3.0)); a.set2d(1, 1, double(4.0))
b: numpy.ndarray[double] | t.CPtr = numpy.empty2d(pool, 2, 2)
b: numpy.ndarray[double]* = numpy.empty2d(pool, 2, 2)
b.set2d(0, 0, double(5.0)); b.set2d(0, 1, double(6.0))
b.set2d(1, 0, double(7.0)); b.set2d(1, 1, double(8.0))
c: numpy.ndarray[double] | t.CPtr = numpy.matmul(a, b)
c: numpy.ndarray[double]* = numpy.matmul(a, b)
check("matmul not None", c != None, "matmul returned None")
check("matmul [0,0]==19", c.at2d(0, 0) == double(19.0), "mismatch")
check("matmul [0,1]==22", c.at2d(0, 1) == double(22.0), "mismatch")
@@ -351,8 +351,8 @@ def test_matmul():
def test_dot():
section_header("dot / dot_product")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(2.0), double(3.0))
b: numpy.ndarray[double] | t.CPtr = vec3(pool, double(4.0), double(5.0), double(6.0))
a: numpy.ndarray[double]* = vec3(pool, double(1.0), double(2.0), double(3.0))
b: numpy.ndarray[double]* = vec3(pool, double(4.0), double(5.0), double(6.0))
d: double = a.dot(b)
check("dot == 32", approx_eq(d, double(32.0)), "mismatch")
@@ -368,11 +368,11 @@ def test_dot():
def test_transpose():
section_header("T (transpose)")
a: numpy.ndarray[double] | t.CPtr = numpy.empty2d(pool, 2, 3)
a: numpy.ndarray[double]* = numpy.empty2d(pool, 2, 3)
a.set2d(0, 0, double(1.0)); a.set2d(0, 1, double(2.0)); a.set2d(0, 2, double(3.0))
a.set2d(1, 0, double(4.0)); a.set2d(1, 1, double(5.0)); a.set2d(1, 2, double(6.0))
at: numpy.ndarray[double] | t.CPtr = a.T()
at: numpy.ndarray[double]* = a.T()
check("T not None", at != None, "T returned None")
check("T shape[0]==3", at.shape[0] == 3, "shape mismatch")
check("T shape[1]==2", at.shape[1] == 2, "shape mismatch")
@@ -392,7 +392,7 @@ def test_var_std_norm():
section_header("var / std / norm")
# [2,4,4,4,5,5,7,9] mean=5, var=4, std=2
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 8)
a: numpy.ndarray[double]* = numpy.zeros(pool, 8)
a.data[0] = double(2.0); a.data[1] = double(4.0)
a.data[2] = double(4.0); a.data[3] = double(4.0)
a.data[4] = double(5.0); a.data[5] = double(5.0)
@@ -406,7 +406,7 @@ def test_var_std_norm():
printf(" std = %.6f (expect 2.0)\n", s)
check("std ~= 2", approx_eq(s, double(2.0)), "mismatch")
b: numpy.ndarray[double] | t.CPtr = vec2(pool, double(3.0), double(4.0))
b: numpy.ndarray[double]* = vec2(pool, double(3.0), double(4.0))
n: double = numpy.norm(b)
printf(" norm = %.6f (expect 5.0)\n", n)
check("norm ~= 5", approx_eq(n, double(5.0)), "mismatch")
@@ -419,15 +419,15 @@ def test_var_std_norm():
def test_clip_concatenate():
section_header("clip / concatenate")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(5.0), double(10.0))
r: numpy.ndarray[double] | t.CPtr = numpy.clip(a, double(2.0), double(8.0))
a: numpy.ndarray[double]* = vec3(pool, double(1.0), double(5.0), double(10.0))
r: numpy.ndarray[double]* = numpy.clip(a, double(2.0), double(8.0))
check("clip [0]==2", r.data[0] == double(2.0), "mismatch")
check("clip [1]==5", r.data[1] == double(5.0), "mismatch")
check("clip [2]==8", r.data[2] == double(8.0), "mismatch")
b: numpy.ndarray[double] | t.CPtr = vec2(pool, double(1.0), double(2.0))
c: numpy.ndarray[double] | t.CPtr = vec2(pool, double(3.0), double(4.0))
cat: numpy.ndarray[double] | t.CPtr = numpy.concatenate(b, c)
b: numpy.ndarray[double]* = vec2(pool, double(1.0), double(2.0))
c: numpy.ndarray[double]* = vec2(pool, double(3.0), double(4.0))
cat: numpy.ndarray[double]* = numpy.concatenate(b, c)
check("concatenate not None", cat != None, "concatenate returned None")
check("concatenate size == 4", cat.size == 4, "size mismatch")
check("concatenate [0]==1", cat.data[0] == double(1.0), "mismatch")
@@ -444,14 +444,14 @@ def test_clip_concatenate():
def test_sort_reverse():
section_header("sort_arr / reverse")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(3.0), double(1.0), double(2.0))
s: numpy.ndarray[double] | t.CPtr = numpy.sort_arr(a)
a: numpy.ndarray[double]* = vec3(pool, double(3.0), double(1.0), double(2.0))
s: numpy.ndarray[double]* = numpy.sort_arr(a)
check("sort not None", s != None, "sort returned None")
check("sort [0]==1", s.data[0] == double(1.0), "mismatch")
check("sort [1]==2", s.data[1] == double(2.0), "mismatch")
check("sort [2]==3", s.data[2] == double(3.0), "mismatch")
r: numpy.ndarray[double] | t.CPtr = numpy.reverse(a)
r: numpy.ndarray[double]* = numpy.reverse(a)
check("reverse not None", r != None, "reverse returned None")
check("reverse [0]==2", r.data[0] == double(2.0), "mismatch")
check("reverse [1]==1", r.data[1] == double(1.0), "mismatch")
@@ -466,11 +466,11 @@ def test_sort_reverse():
def test_print_arr():
section_header("print_arr")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(2.0), double(3.0))
a: numpy.ndarray[double]* = vec3(pool, double(1.0), double(2.0), double(3.0))
printf(" 1D array: ")
a.print_arr()
b: numpy.ndarray[double] | t.CPtr = numpy.eye(pool, 3)
b: numpy.ndarray[double]* = numpy.eye(pool, 3)
printf(" 2D eye(3):\n")
b.print_arr()
@@ -485,15 +485,15 @@ def test_print_arr():
def test_floordiv_mod():
section_header("__floordiv__ / __mod__")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(7.0), double(10.0), double(15.0))
b: numpy.ndarray[double] | t.CPtr = vec3(pool, double(2.0), double(3.0), double(4.0))
a: numpy.ndarray[double]* = vec3(pool, double(7.0), double(10.0), double(15.0))
b: numpy.ndarray[double]* = vec3(pool, double(2.0), double(3.0), double(4.0))
c_fd: numpy.ndarray[double] | t.CPtr = a // b
c_fd: numpy.ndarray[double]* = a // b
check("7//2==3", c_fd.data[0] == double(3.0), "mismatch")
check("10//3==3", c_fd.data[1] == double(3.0), "mismatch")
check("15//4==3", c_fd.data[2] == double(3.0), "mismatch")
c_mod: numpy.ndarray[double] | t.CPtr = a % b
c_mod: numpy.ndarray[double]* = a % b
check("7%%2==1", c_mod.data[0] == double(1.0), "mismatch")
check("10%%3==1", c_mod.data[1] == double(1.0), "mismatch")
check("15%%4==3", c_mod.data[2] == double(3.0), "mismatch")
@@ -511,35 +511,35 @@ def test_floordiv_mod():
def test_additional_math():
section_header("np_log10 / np_log2 / np_floor / np_ceil / np_round / np_sign")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(10.0), double(100.0), double(1000.0))
r_log10: numpy.ndarray[double] | t.CPtr = numpy.np_log10(a)
a: numpy.ndarray[double]* = vec3(pool, double(10.0), double(100.0), double(1000.0))
r_log10: numpy.ndarray[double]* = numpy.np_log10(a)
check("log10(10)~=1", approx_loose(r_log10.data[0], double(1.0)), "mismatch")
check("log10(100)~=2", approx_loose(r_log10.data[1], double(2.0)), "mismatch")
b: numpy.ndarray[double] | t.CPtr = vec3(pool, double(2.0), double(4.0), double(8.0))
r_log2: numpy.ndarray[double] | t.CPtr = numpy.np_log2(b)
b: numpy.ndarray[double]* = vec3(pool, double(2.0), double(4.0), double(8.0))
r_log2: numpy.ndarray[double]* = numpy.np_log2(b)
check("log2(2)~=1", approx_loose(r_log2.data[0], double(1.0)), "mismatch")
check("log2(4)~=2", approx_loose(r_log2.data[1], double(2.0)), "mismatch")
c: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.5), double(2.7), double(-1.3))
r_floor: numpy.ndarray[double] | t.CPtr = numpy.np_floor(c)
c: numpy.ndarray[double]* = vec3(pool, double(1.5), double(2.7), double(-1.3))
r_floor: numpy.ndarray[double]* = numpy.np_floor(c)
check("floor(1.5)==1", r_floor.data[0] == double(1.0), "mismatch")
check("floor(2.7)==2", r_floor.data[1] == double(2.0), "mismatch")
check("floor(-1.3)==-2", r_floor.data[2] == double(-2.0), "mismatch")
r_ceil: numpy.ndarray[double] | t.CPtr = numpy.np_ceil(c)
r_ceil: numpy.ndarray[double]* = numpy.np_ceil(c)
check("ceil(1.5)==2", r_ceil.data[0] == double(2.0), "mismatch")
check("ceil(2.7)==3", r_ceil.data[1] == double(3.0), "mismatch")
check("ceil(-1.3)==-1", r_ceil.data[2] == double(-1.0), "mismatch")
d: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.4), double(2.5), double(3.6))
r_round: numpy.ndarray[double] | t.CPtr = numpy.np_round(d)
d: numpy.ndarray[double]* = vec3(pool, double(1.4), double(2.5), double(3.6))
r_round: numpy.ndarray[double]* = numpy.np_round(d)
check("round(1.4)==1", r_round.data[0] == double(1.0), "mismatch")
check("round(3.6)==4", r_round.data[2] == double(4.0), "mismatch")
e: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
e: numpy.ndarray[double]* = numpy.zeros(pool, 4)
e.data[0] = double(-3.0); e.data[1] = double(0.0); e.data[2] = double(5.0); e.data[3] = double(-0.1)
r_sign: numpy.ndarray[double] | t.CPtr = numpy.np_sign(e)
r_sign: numpy.ndarray[double]* = numpy.np_sign(e)
check("sign(-3)==-1", r_sign.data[0] == double(-1.0), "mismatch")
check("sign(0)==0", r_sign.data[1] == double(0.0), "mismatch")
check("sign(5)==1", r_sign.data[2] == double(1.0), "mismatch")
@@ -561,25 +561,25 @@ def test_additional_math():
def test_trig_hyperbolic():
section_header("np_tanh / np_sinh / np_cosh / np_arcsin / np_arccos / np_arctan")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(0.0), double(1.0), double(-1.0))
a: numpy.ndarray[double]* = vec3(pool, double(0.0), double(1.0), double(-1.0))
r_tanh: numpy.ndarray[double] | t.CPtr = numpy.np_tanh(a)
r_tanh: numpy.ndarray[double]* = numpy.np_tanh(a)
check("tanh(0)~=0", approx_loose(r_tanh.data[0], double(0.0)), "mismatch")
r_sinh: numpy.ndarray[double] | t.CPtr = numpy.np_sinh(a)
r_sinh: numpy.ndarray[double]* = numpy.np_sinh(a)
check("sinh(0)~=0", approx_loose(r_sinh.data[0], double(0.0)), "mismatch")
r_cosh: numpy.ndarray[double] | t.CPtr = numpy.np_cosh(a)
r_cosh: numpy.ndarray[double]* = numpy.np_cosh(a)
check("cosh(0)~=1", approx_loose(r_cosh.data[0], double(1.0)), "mismatch")
b: numpy.ndarray[double] | t.CPtr = vec2(pool, double(0.0), double(0.5))
r_asin: numpy.ndarray[double] | t.CPtr = numpy.np_arcsin(b)
b: numpy.ndarray[double]* = vec2(pool, double(0.0), double(0.5))
r_asin: numpy.ndarray[double]* = numpy.np_arcsin(b)
check("arcsin(0)~=0", approx_loose(r_asin.data[0], double(0.0)), "mismatch")
r_acos: numpy.ndarray[double] | t.CPtr = numpy.np_arccos(b)
r_acos: numpy.ndarray[double]* = numpy.np_arccos(b)
check("arccos(0)~=pi/2", approx_loose(r_acos.data[0], double(1.5707963)), "mismatch")
r_atan: numpy.ndarray[double] | t.CPtr = numpy.np_arctan(b)
r_atan: numpy.ndarray[double]* = numpy.np_arctan(b)
check("arctan(0)~=0", approx_loose(r_atan.data[0], double(0.0)), "mismatch")
a.delete()
@@ -596,14 +596,14 @@ def test_trig_hyperbolic():
def test_degrees_radians():
section_header("np_degrees / np_radians")
a: numpy.ndarray[double] | t.CPtr = vec2(pool, double(0.0), double(1.5707963267948966))
a: numpy.ndarray[double]* = vec2(pool, double(0.0), double(1.5707963267948966))
r_deg: numpy.ndarray[double] | t.CPtr = numpy.np_degrees(a)
r_deg: numpy.ndarray[double]* = numpy.np_degrees(a)
check("deg(0)~=0", approx_loose(r_deg.data[0], double(0.0)), "mismatch")
check("deg(pi/2)~=90", approx_loose(r_deg.data[1], double(90.0)), "mismatch")
b: numpy.ndarray[double] | t.CPtr = vec2(pool, double(0.0), double(90.0))
r_rad: numpy.ndarray[double] | t.CPtr = numpy.np_radians(b)
b: numpy.ndarray[double]* = vec2(pool, double(0.0), double(90.0))
r_rad: numpy.ndarray[double]* = numpy.np_radians(b)
check("rad(0)~=0", approx_loose(r_rad.data[0], double(0.0)), "mismatch")
check("rad(90)~=pi/2", approx_loose(r_rad.data[1], double(1.5707963)), "mismatch")
@@ -620,17 +620,17 @@ def test_degrees_radians():
def test_cumsum_diff():
section_header("cumsum / diff")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
a: numpy.ndarray[double]* = numpy.zeros(pool, 4)
a.data[0] = double(1.0); a.data[1] = double(2.0); a.data[2] = double(3.0); a.data[3] = double(4.0)
r_cs: numpy.ndarray[double] | t.CPtr = numpy.cumsum(a)
r_cs: numpy.ndarray[double]* = numpy.cumsum(a)
check("cumsum not None", r_cs != None, "cumsum returned None")
check("cumsum[0]==1", r_cs.data[0] == double(1.0), "mismatch")
check("cumsum[1]==3", r_cs.data[1] == double(3.0), "mismatch")
check("cumsum[2]==6", r_cs.data[2] == double(6.0), "mismatch")
check("cumsum[3]==10", r_cs.data[3] == double(10.0), "mismatch")
r_diff: numpy.ndarray[double] | t.CPtr = numpy.diff(a)
r_diff: numpy.ndarray[double]* = numpy.diff(a)
check("diff not None", r_diff != None, "diff returned None")
check("diff size==3", r_diff.size == 3, "size mismatch")
check("diff[0]==1", r_diff.data[0] == double(1.0), "mismatch")
@@ -645,22 +645,22 @@ def test_cumsum_diff():
def test_max_min_where():
section_header("np_maximum / np_minimum / np_where")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(5.0), double(3.0))
b: numpy.ndarray[double] | t.CPtr = vec3(pool, double(4.0), double(2.0), double(6.0))
a: numpy.ndarray[double]* = vec3(pool, double(1.0), double(5.0), double(3.0))
b: numpy.ndarray[double]* = vec3(pool, double(4.0), double(2.0), double(6.0))
r_max: numpy.ndarray[double] | t.CPtr = numpy.np_maximum(a, b)
r_max: numpy.ndarray[double]* = numpy.np_maximum(a, b)
check("maximum[0]==4", r_max.data[0] == double(4.0), "mismatch")
check("maximum[1]==5", r_max.data[1] == double(5.0), "mismatch")
check("maximum[2]==6", r_max.data[2] == double(6.0), "mismatch")
r_min: numpy.ndarray[double] | t.CPtr = numpy.np_minimum(a, b)
r_min: numpy.ndarray[double]* = numpy.np_minimum(a, b)
check("minimum[0]==1", r_min.data[0] == double(1.0), "mismatch")
check("minimum[1]==2", r_min.data[1] == double(2.0), "mismatch")
check("minimum[2]==3", r_min.data[2] == double(3.0), "mismatch")
# where: cond > 0 ? a : b
cond: numpy.ndarray[double] | t.CPtr = vec3(pool, double(0.0), double(1.0), double(0.0))
r_where: numpy.ndarray[double] | t.CPtr = numpy.np_where(cond, a, b)
cond: numpy.ndarray[double]* = vec3(pool, double(0.0), double(1.0), double(0.0))
r_where: numpy.ndarray[double]* = numpy.np_where(cond, a, b)
check("where[0]==4", r_where.data[0] == double(4.0), "mismatch")
check("where[1]==5", r_where.data[1] == double(5.0), "mismatch")
check("where[2]==6", r_where.data[2] == double(6.0), "mismatch")
@@ -677,18 +677,18 @@ def test_max_min_where():
def test_flatten_trace():
section_header("flatten / trace")
a: numpy.ndarray[double] | t.CPtr = numpy.empty2d(pool, 2, 3)
a: numpy.ndarray[double]* = numpy.empty2d(pool, 2, 3)
a.set2d(0, 0, double(1.0)); a.set2d(0, 1, double(2.0)); a.set2d(0, 2, double(3.0))
a.set2d(1, 0, double(4.0)); a.set2d(1, 1, double(5.0)); a.set2d(1, 2, double(6.0))
r_flat: numpy.ndarray[double] | t.CPtr = numpy.flatten(a)
r_flat: numpy.ndarray[double]* = numpy.flatten(a)
check("flatten not None", r_flat != None, "flatten returned None")
check("flatten ndim==1", r_flat.ndim == 1, "ndim mismatch")
check("flatten size==6", r_flat.size == 6, "size mismatch")
check("flatten[0]==1", r_flat.data[0] == double(1.0), "mismatch")
# trace of [[1,2],[3,4]] = 1+4 = 5
b: numpy.ndarray[double] | t.CPtr = numpy.empty2d(pool, 2, 2)
b: numpy.ndarray[double]* = numpy.empty2d(pool, 2, 2)
b.set2d(0, 0, double(1.0)); b.set2d(0, 1, double(2.0))
b.set2d(1, 0, double(3.0)); b.set2d(1, 1, double(4.0))
tr: double = numpy.trace(b)
@@ -703,10 +703,10 @@ def test_flatten_trace():
def test_outer():
section_header("outer")
a: numpy.ndarray[double] | t.CPtr = vec2(pool, double(1.0), double(2.0))
b: numpy.ndarray[double] | t.CPtr = vec3(pool, double(3.0), double(4.0), double(5.0))
a: numpy.ndarray[double]* = vec2(pool, double(1.0), double(2.0))
b: numpy.ndarray[double]* = vec3(pool, double(3.0), double(4.0), double(5.0))
r: numpy.ndarray[double] | t.CPtr = numpy.outer(a, b)
r: numpy.ndarray[double]* = numpy.outer(a, b)
check("outer not None", r != None, "outer returned None")
check("outer ndim==2", r.ndim == 2, "ndim mismatch")
check("outer[0,0]==3", r.at2d(0, 0) == double(3.0), "mismatch")
@@ -726,30 +726,30 @@ def test_outer():
def test_bool_comparison():
section_header("np_all / np_any / np_count_nonzero / np_equal / np_less / np_greater")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
a: numpy.ndarray[double]* = numpy.zeros(pool, 4)
a.data[0] = double(1.0); a.data[1] = double(0.0); a.data[2] = double(3.0); a.data[3] = double(0.0)
check("count_nonzero==2", numpy.np_count_nonzero(a) == 2, "mismatch")
check("any==1", numpy.np_any(a) == 1, "mismatch")
b: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(2.0), double(3.0))
b: numpy.ndarray[double]* = vec3(pool, double(1.0), double(2.0), double(3.0))
check("all(1,2,3)==1", numpy.np_all(b) == 1, "mismatch")
c: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 3)
c: numpy.ndarray[double]* = numpy.zeros(pool, 3)
check("all(0,0,0)==0", numpy.np_all(c) == 0, "mismatch")
check("any(0,0,0)==0", numpy.np_any(c) == 0, "mismatch")
d: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(2.0), double(3.0))
e: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(0.0), double(4.0))
d: numpy.ndarray[double]* = vec3(pool, double(1.0), double(2.0), double(3.0))
e: numpy.ndarray[double]* = vec3(pool, double(1.0), double(0.0), double(4.0))
r_eq: numpy.ndarray[double] | t.CPtr = numpy.np_equal(d, e)
r_eq: numpy.ndarray[double]* = numpy.np_equal(d, e)
check("equal[0]==1", r_eq.data[0] == double(1.0), "mismatch")
check("equal[1]==0", r_eq.data[1] == double(0.0), "mismatch")
r_lt: numpy.ndarray[double] | t.CPtr = numpy.np_less(d, e)
r_lt: numpy.ndarray[double]* = numpy.np_less(d, e)
check("less[2]==1", r_lt.data[2] == double(1.0), "mismatch")
check("less[0]==0", r_lt.data[0] == double(0.0), "mismatch")
r_gt: numpy.ndarray[double] | t.CPtr = numpy.np_greater(d, e)
r_gt: numpy.ndarray[double]* = numpy.np_greater(d, e)
check("greater[1]==1", r_gt.data[1] == double(1.0), "mismatch")
a.delete()
@@ -770,32 +770,32 @@ def test_linalg():
section_header("det2x2 / inv2x2 / cross3 / prod / median / percentile")
# det2x2: [[1,2],[3,4]] -> 1*4-2*3 = -2
a: numpy.ndarray[double] | t.CPtr = numpy.empty2d(pool, 2, 2)
a: numpy.ndarray[double]* = numpy.empty2d(pool, 2, 2)
a.set2d(0, 0, double(1.0)); a.set2d(0, 1, double(2.0))
a.set2d(1, 0, double(3.0)); a.set2d(1, 1, double(4.0))
d: double = numpy.det2x2(a)
check("det2x2==-2", d == double(-2.0), "mismatch")
# inv2x2 of [[1,2],[3,4]]
inv: numpy.ndarray[double] | t.CPtr = numpy.inv2x2(a)
inv: numpy.ndarray[double]* = numpy.inv2x2(a)
check("inv2x2 not None", inv != None, "inv2x2 returned None")
check("inv[0,0]==-2", approx_eq(inv.at2d(0, 0), double(-2.0)), "mismatch")
check("inv[0,1]==1", approx_eq(inv.at2d(0, 1), double(1.0)), "mismatch")
# cross3: [1,0,0] x [0,1,0] = [0,0,1]
x: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(0.0), double(0.0))
y: numpy.ndarray[double] | t.CPtr = vec3(pool, double(0.0), double(1.0), double(0.0))
cr: numpy.ndarray[double] | t.CPtr = numpy.cross3(x, y)
x: numpy.ndarray[double]* = vec3(pool, double(1.0), double(0.0), double(0.0))
y: numpy.ndarray[double]* = vec3(pool, double(0.0), double(1.0), double(0.0))
cr: numpy.ndarray[double]* = numpy.cross3(x, y)
check("cross not None", cr != None, "cross returned None")
check("cross[2]==1", cr.data[2] == double(1.0), "mismatch")
# prod
p: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
p: numpy.ndarray[double]* = numpy.zeros(pool, 4)
p.data[0] = double(1.0); p.data[1] = double(2.0); p.data[2] = double(3.0); p.data[3] = double(4.0)
check("prod==24", numpy.prod(p) == double(24.0), "mismatch")
# median
m: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 5)
m: numpy.ndarray[double]* = numpy.zeros(pool, 5)
m.data[0] = double(3.0); m.data[1] = double(1.0); m.data[2] = double(2.0)
m.data[3] = double(5.0); m.data[4] = double(4.0)
check("median==3", numpy.median(m) == double(3.0), "mismatch")
@@ -819,23 +819,23 @@ def test_linalg():
def test_additional_creation():
section_header("full2d / zeros_like / ones_like / arange1 / constants")
f: numpy.ndarray[double] | t.CPtr = numpy.full2d(pool, 2, 3, double(7.0))
f: numpy.ndarray[double]* = numpy.full2d(pool, 2, 3, double(7.0))
check("full2d not None", f != None, "full2d returned None")
check("full2d ndim==2", f.ndim == 2, "ndim mismatch")
check("full2d[0,0]==7", f.at2d(0, 0) == double(7.0), "mismatch")
check("full2d[1,2]==7", f.at2d(1, 2) == double(7.0), "mismatch")
a: numpy.ndarray[double] | t.CPtr = vec3(pool, double(1.0), double(2.0), double(3.0))
zl: numpy.ndarray[double] | t.CPtr = numpy.zeros_like(a)
a: numpy.ndarray[double]* = vec3(pool, double(1.0), double(2.0), double(3.0))
zl: numpy.ndarray[double]* = numpy.zeros_like(a)
check("zeros_like not None", zl != None, "returned None")
check("zeros_like size==3", zl.size == 3, "size mismatch")
check("zeros_like[0]==0", zl.data[0] == double(0.0), "mismatch")
ol: numpy.ndarray[double] | t.CPtr = numpy.ones_like(a)
ol: numpy.ndarray[double]* = numpy.ones_like(a)
check("ones_like not None", ol != None, "returned None")
check("ones_like[0]==1", ol.data[0] == double(1.0), "mismatch")
ar: numpy.ndarray[double] | t.CPtr = numpy.arange1(pool, double(4.0))
ar: numpy.ndarray[double]* = numpy.arange1(pool, double(4.0))
check("arange1 not None", ar != None, "returned None")
check("arange1 size==4", ar.size == 4, "size mismatch")
check("arange1[0]==0", ar.data[0] == double(0.0), "mismatch")
@@ -859,8 +859,8 @@ def test_additional_creation():
def test_interp():
section_header("np_interp")
xp: numpy.ndarray[double] | t.CPtr = vec3(pool, double(0.0), double(1.0), double(2.0))
fp: numpy.ndarray[double] | t.CPtr = vec3(pool, double(0.0), double(10.0), double(20.0))
xp: numpy.ndarray[double]* = vec3(pool, double(0.0), double(1.0), double(2.0))
fp: numpy.ndarray[double]* = vec3(pool, double(0.0), double(10.0), double(20.0))
v: double = numpy.np_interp(double(0.5), xp, fp)
check("interp(0.5)==5", approx_eq(v, double(5.0)), "mismatch")
@@ -886,33 +886,33 @@ def test_numpy_edge():
section_header("edge: size=0 / size=1 / non-SIMD-block / negative / div-zero")
# size=0: pool.alloc(0) returns None, so zeros(0) returns None (expected)
a0: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 0)
a0: numpy.ndarray[double]* = numpy.zeros(pool, 0)
check("zeros(0) returns None", a0 == None, "expected None for size=0")
# size=1
a1: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 1)
a1: numpy.ndarray[double]* = numpy.zeros(pool, 1)
check("zeros(1) not None", a1 != None, "returned None")
check("zeros(1) size==1", a1.size == 1, "size mismatch")
check("zeros(1) [0]==0", a1.data[0] == double(0.0), "mismatch")
a1.delete()
# non-SIMD-block sizes (1,2,3,5,6,7)
a5: numpy.ndarray[double] | t.CPtr = numpy.arange(pool, double(0.0), double(5.0), double(1.0))
a5: numpy.ndarray[double]* = numpy.arange(pool, double(0.0), double(5.0), double(1.0))
check("arange(5) size==5", a5.size == 5, "size mismatch")
check("arange(5) sum==10", approx_eq(a5.sum(), double(10.0)), "mismatch")
a5.delete()
a6: numpy.ndarray[double] | t.CPtr = numpy.arange(pool, double(0.0), double(6.0), double(1.0))
a6: numpy.ndarray[double]* = numpy.arange(pool, double(0.0), double(6.0), double(1.0))
check("arange(6) sum==15", approx_eq(a6.sum(), double(15.0)), "mismatch")
a6.delete()
a7: numpy.ndarray[double] | t.CPtr = numpy.arange(pool, double(0.0), double(7.0), double(1.0))
a7: numpy.ndarray[double]* = numpy.arange(pool, double(0.0), double(7.0), double(1.0))
check("arange(7) sum==21", approx_eq(a7.sum(), double(21.0)), "mismatch")
a7.delete()
# negative values in sqrt
neg_arr: numpy.ndarray[double] | t.CPtr = vec3(pool, double(-1.0), double(0.0), double(4.0))
r_sqrt_neg: numpy.ndarray[double] | t.CPtr = numpy.np_sqrt(neg_arr)
neg_arr: numpy.ndarray[double]* = vec3(pool, double(-1.0), double(0.0), double(4.0))
r_sqrt_neg: numpy.ndarray[double]* = numpy.np_sqrt(neg_arr)
check("sqrt(neg) not None", r_sqrt_neg != None, "returned None")
# sqrt(4)=2, sqrt(0)=0; sqrt(-1) is NaN (implementation-defined)
check("sqrt(4)==2", approx_eq(r_sqrt_neg.data[2], double(2.0)), "mismatch")
@@ -920,9 +920,9 @@ def test_numpy_edge():
r_sqrt_neg.delete()
# div-by-zero: b/a where a has zeros
za: numpy.ndarray[double] | t.CPtr = vec3(pool, double(0.0), double(2.0), double(0.0))
zb: numpy.ndarray[double] | t.CPtr = vec3(pool, double(6.0), double(4.0), double(8.0))
r_divz: numpy.ndarray[double] | t.CPtr = za / zb
za: numpy.ndarray[double]* = vec3(pool, double(0.0), double(2.0), double(0.0))
zb: numpy.ndarray[double]* = vec3(pool, double(6.0), double(4.0), double(8.0))
r_divz: numpy.ndarray[double]* = za / zb
check("0/6==0", r_divz.data[0] == double(0.0), "mismatch")
check("2/4==0.5", r_divz.data[1] == double(0.5), "mismatch")
za.delete()
@@ -930,7 +930,7 @@ def test_numpy_edge():
r_divz.delete()
# large array (non-aligned, non-SIMD-block)
big: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 1000)
big: numpy.ndarray[double]* = numpy.zeros(pool, 1000)
check("zeros(1000) not None", big != None, "returned None")
check("zeros(1000) size==1000", big.size == 1000, "size mismatch")
big.delete()
@@ -947,41 +947,33 @@ def bench_numpy_perf():
N: sizet = 10000
ITERS: int = 5
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, N)
b: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, N)
i: sizet = 0
while i < N:
a: numpy.ndarray[double]* = numpy.zeros(pool, N)
b: numpy.ndarray[double]* = numpy.zeros(pool, N)
for i in range(N):
a.data[i] = double(1.0)
b.data[i] = double(2.0)
i += 1
# add benchmark
t0: double = timer_sec()
j: int = 0
while j < ITERS:
r: numpy.ndarray[double] | t.CPtr = a + b
for j in range(ITERS):
r: numpy.ndarray[double]* = a + b
r.delete()
j += 1
t1: double = timer_sec()
printf(" ADD: %.1f ms\n", (t1 - t0) * double(1000.0))
# mul benchmark
t0 = timer_sec()
j = 0
while j < ITERS:
r2: numpy.ndarray[double] | t.CPtr = a * b
for j in range(ITERS):
r2: numpy.ndarray[double]* = a * b
r2.delete()
j += 1
t1 = timer_sec()
printf(" MUL: %.1f ms\n", (t1 - t0) * double(1000.0))
# sqrt benchmark
t0 = timer_sec()
j = 0
while j < ITERS:
r3: numpy.ndarray[double] | t.CPtr = numpy.np_sqrt(a)
for j in range(ITERS):
r3: numpy.ndarray[double]* = numpy.np_sqrt(a)
r3.delete()
j += 1
t1 = timer_sec()
printf(" SQRT: %.1f ms\n", (t1 - t0) * double(1000.0))
+16 -16
View File
@@ -12,7 +12,7 @@ import testcheck
# --- Test 1: global 声明对模块级变量的影响 ---
_g_val: int = 0
_g_ptr: uint32 | t.CPtr = None
_g_ptr: uint32* = None
def test_global_write():
"""测试:缺少 global 声明时,赋值是否修改模块级变量"""
@@ -30,30 +30,30 @@ def test_global_write_no_decl():
def test_global_ptr():
global _g_ptr
buf: uint32 | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
buf: uint32* = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
if buf:
string.memset(buf, 0, 256)
_g_ptr = buf
p: uint32 | t.CPtr = _g_ptr
p: uint32* = _g_ptr
p[0] = 0xAABBCCDD
p[1] = 0x11223344
def test_global_ptr_no_decl():
"""测试:没有 global 声明时,同名注解声明是编译期错误(此处演示合法写法)
新规则:模块级已有 `_g_ptr` 时,函数内写 `_g_ptr: t.CUInt32T | t.CPtr = None`
新规则:模块级已有 `_g_ptr` 时,函数内写 `_g_ptr: t.CUInt32T* = None`
(无 global)或 `global _g_ptr` 之后仍带类型注解声明,都判为"重复声明"并终止
编译(TypeError)——不管注解类型是否与全局相同。合法写法只有两种:
- 修改全局:`global _g_ptr` + **无注解**赋值(见 test_global_ptr)
- 独立局部:换成不与全局重名的变量名(本函数)
"""
local_ptr: uint32 | t.CPtr = None # 独立局部变量,不触碰全局 _g_ptr
local_ptr: uint32* = None # 独立局部变量,不触碰全局 _g_ptr
# --- Test 2: 指针算术和数组索引 ---
def test_pointer_arithmetic():
"""测试指针算术:偏移计算是否正确"""
buf: uint32 | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
buf: uint32* = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
if not buf:
testcheck.fail("pointer arithmetic: VirtualAlloc returned NULL")
return
@@ -93,7 +93,7 @@ def test_array_decay():
# --- Test 4: 指针类型转换 (CVoid/CPtr) ---
def test_pointer_cast():
"""测试指针与整数之间的类型转换"""
buf: uint32 | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
buf: uint32* = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
if not buf:
testcheck.fail("pointer cast: VirtualAlloc returned NULL")
return
@@ -102,7 +102,7 @@ def test_pointer_cast():
# 通过 CVoid 指针写入
raw: t.CPtr = t.CPtr(uint64(buf))
# 将 CVoid 指针转回 CUInt32T 指针
p32: uint32 | t.CPtr = (uint32 | t.CPtr)(raw)
p32: uint32* = (uint32*)(raw)
p32[0] = 0xDEADBEEF
# 通过原始指针读取
@@ -116,7 +116,7 @@ def test_pointer_cast():
# --- Test 5: 指针偏移计算 (byte offset vs element offset) ---
def test_pointer_offset():
"""测试指针偏移:CUInt8T* + N 应该偏移 N 字节,CUInt32T* + N 应该偏移 N*4 字节"""
buf: uint8 | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
buf: uint8* = w32.win32memory.VirtualAlloc(None, 256, 0x3000, 0x04)
if not buf:
testcheck.fail("pointer offset: VirtualAlloc returned NULL")
return
@@ -129,7 +129,7 @@ def test_pointer_offset():
buf[3] = 0x44 # 'D'
# 通过 CUInt32T* 读取(应该读到 0x44434241 on little-endian)
p32: uint32 | t.CPtr = (uint32 | t.CPtr)(t.CPtr(uint64(buf)))
p32: uint32* = (uint32*)(t.CPtr(uint64(buf)))
val: uint32 = p32[0]
# little-endian: 0x44434241
@@ -153,7 +153,7 @@ def test_struct_pointer():
s.b = 20
s.c = 0x123456789ABCDEF0
p: TestStruct | t.CPtr = &s
p: TestStruct* = &s
stdio.printf("struct pointer access (a=%d b=%d c=0x%llx)\n", p.a, p.b, p.c)
testcheck.check(p.a == 10 and p.b == 20 and p.c == 0x123456789ABCDEF0, "struct pointer access", "struct pointer access mismatch")
@@ -161,8 +161,8 @@ def test_struct_pointer():
# --- Test 7: memcpy/memset 通过指针 ---
def test_memcpy_pointers():
"""测试 memcpy 在指针之间的数据复制"""
src_buf: uint32 | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
dst_buf: uint32 | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
src_buf: uint32* = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
dst_buf: uint32* = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
if not src_buf or not dst_buf:
testcheck.fail("memcpy: VirtualAlloc returned NULL")
return
@@ -184,13 +184,13 @@ def test_memcpy_pointers():
# --- Test 8: 指针作为函数参数 ---
def fill_array(arr: uint32 | t.CPtr, count: int, val: uint32):
def fill_array(arr: uint32*, count: int, val: uint32):
for i in range(count):
arr[i] = val
def test_pointer_param():
"""测试指针作为函数参数传递"""
buf: uint32 | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
buf: uint32* = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
if not buf:
testcheck.fail("pointer param: VirtualAlloc returned NULL")
return
@@ -239,7 +239,7 @@ def main() -> int | t.CExport:
testcheck.section("Test 1b: global pointer")
test_global_ptr()
if _g_ptr:
p: uint32 | t.CPtr = _g_ptr
p: uint32* = _g_ptr
stdio.printf("_g_ptr[0] = 0x%x (expect 0xAABBCCDD)\n", p[0])
stdio.printf("_g_ptr[1] = 0x%x (expect 0x11223344)\n", p[1])
testcheck.check(p[0] == 0xAABBCCDD and p[1] == 0x11223344, "global pointer values", "global pointer mismatch")
+2 -2
View File
@@ -46,7 +46,7 @@ import w32.win32console as w32console
# 只声明不调用:extern 声明未调用不产生链接引用,不影响链接
# 先例:Test/Extern2Test/App/main.vp:18-35(三个仅声明不调用的外部声明)
# ============================================================
extern def ProbeNestedUnion(Context: VOIDPTR | t.CPtr) -> BOOL
extern def ProbeNestedUnion(Context: VOIDPTR*) -> BOOL
# ============================================================
@@ -128,7 +128,7 @@ def ProbeU8Literal() -> uint8:
# (class Translator: def __init__(self): ...;实例化 TransPyV/App/main.vp:471)
# ============================================================
class Box:
p: char | t.CPtr
p: char*
def __init__(self):
self.p = None
+49 -67
View File
@@ -10,8 +10,8 @@ import testcheck
# 全局内存池
arena: uint8 | t.CPtr = None
pool: memhub.MemPool | t.CPtr = None
arena: uint8* = None
pool: memhub.MemPool* = None
# 外部函数: clock() 用于性能计时
def clock() -> t.CLong | t.CExtern: pass
@@ -25,19 +25,19 @@ define CLOCK_PER_SEC = 1000
def test_avx2_add_sub_mul_div():
testcheck.section("AVX2 add/sub/mul/div 4d")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
a: numpy.ndarray[double]* = numpy.zeros(pool, 4)
a.data[0] = double(1.0)
a.data[1] = double(2.0)
a.data[2] = double(3.0)
a.data[3] = double(4.0)
b: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
b: numpy.ndarray[double]* = numpy.zeros(pool, 4)
b.data[0] = double(5.0)
b.data[1] = double(6.0)
b.data[2] = double(7.0)
b.data[3] = double(8.0)
out: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
out: numpy.ndarray[double]* = numpy.zeros(pool, 4)
# add
vipersimd.simd_add4d(a.data, b.data, out.data)
@@ -70,13 +70,13 @@ def test_avx2_add_sub_mul_div():
def test_avx2_neg_abs_sqrt():
testcheck.section("AVX2 neg/abs/sqrt 4d")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
a: numpy.ndarray[double]* = numpy.zeros(pool, 4)
a.data[0] = double(1.0)
a.data[1] = double(-4.0)
a.data[2] = double(9.0)
a.data[3] = double(-16.0)
out: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
out: numpy.ndarray[double]* = numpy.zeros(pool, 4)
# neg
vipersimd.simd_neg4d(a.data, out.data)
@@ -105,19 +105,19 @@ def test_avx2_neg_abs_sqrt():
def test_avx2_min_max():
testcheck.section("AVX2 min/max 4d")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
a: numpy.ndarray[double]* = numpy.zeros(pool, 4)
a.data[0] = double(1.0)
a.data[1] = double(8.0)
a.data[2] = double(3.0)
a.data[3] = double(6.0)
b: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
b: numpy.ndarray[double]* = numpy.zeros(pool, 4)
b.data[0] = double(5.0)
b.data[1] = double(2.0)
b.data[2] = double(7.0)
b.data[3] = double(4.0)
out: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
out: numpy.ndarray[double]* = numpy.zeros(pool, 4)
vipersimd.simd_min4d(a.data, b.data, out.data)
testcheck.check(out.data[0] == double(1.0), "min[0]==1", "min[0]==1")
@@ -138,16 +138,16 @@ def test_avx2_min_max():
def test_avx2_scalar_ops():
testcheck.section("AVX2 scalar broadcast ops")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
a: numpy.ndarray[double]* = numpy.zeros(pool, 4)
a.data[0] = double(1.0)
a.data[1] = double(2.0)
a.data[2] = double(3.0)
a.data[3] = double(4.0)
s: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 1)
s: numpy.ndarray[double]* = numpy.zeros(pool, 1)
s.data[0] = double(10.0)
out: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
out: numpy.ndarray[double]* = numpy.zeros(pool, 4)
vipersimd.simd_mul_scalar4d(a.data, s.data, out.data)
testcheck.check(out.data[0] == double(10.0), "mul_scalar[0]==10", "mul_scalar[0]==10")
@@ -165,19 +165,19 @@ def test_avx2_scalar_ops():
def test_avx2_hsum_dot():
testcheck.section("AVX2 hsum/dot 4d")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
a: numpy.ndarray[double]* = numpy.zeros(pool, 4)
a.data[0] = double(1.0)
a.data[1] = double(2.0)
a.data[2] = double(3.0)
a.data[3] = double(4.0)
b: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
b: numpy.ndarray[double]* = numpy.zeros(pool, 4)
b.data[0] = double(5.0)
b.data[1] = double(6.0)
b.data[2] = double(7.0)
b.data[3] = double(8.0)
out: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 1)
out: numpy.ndarray[double]* = numpy.zeros(pool, 1)
vipersimd.simd_hsum4d(a.data, out.data)
testcheck.check(out.data[0] == double(10.0), "hsum==10", "hsum==10")
@@ -192,21 +192,21 @@ def test_avx2_hsum_dot():
def test_avx2_fma():
testcheck.section("AVX2 FMA 4d")
a: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
a: numpy.ndarray[double]* = numpy.zeros(pool, 4)
a.data[0] = double(1.0)
a.data[1] = double(2.0)
a.data[2] = double(3.0)
a.data[3] = double(4.0)
b: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
b: numpy.ndarray[double]* = numpy.zeros(pool, 4)
b.data[0] = double(5.0)
b.data[1] = double(6.0)
b.data[2] = double(7.0)
b.data[3] = double(8.0)
c_val: numpy.ndarray[double] | t.CPtr = numpy.ones(pool, 4)
c_val: numpy.ndarray[double]* = numpy.ones(pool, 4)
out: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
out: numpy.ndarray[double]* = numpy.zeros(pool, 4)
vipersimd.simd_fma4d(a.data, b.data, c_val.data, out.data)
testcheck.check(out.data[0] == double(6.0), "fma[0]==6", "fma[0]==6")
@@ -227,9 +227,9 @@ def test_avx2_fma():
def test_batch_array_ops():
testcheck.section("Batch array operations")
n: sizet = 16
a: numpy.ndarray[double] | t.CPtr = numpy.arange(pool, double(1.0), double(17.0), double(1.0))
b: numpy.ndarray[double] | t.CPtr = numpy.full(pool, 16, double(2.0))
out: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 16)
a: numpy.ndarray[double]* = numpy.arange(pool, double(1.0), double(17.0), double(1.0))
b: numpy.ndarray[double]* = numpy.full(pool, 16, double(2.0))
out: numpy.ndarray[double]* = numpy.zeros(pool, 16)
# add array
vipersimd.simd_add_array(a.data, b.data, out.data, n)
@@ -242,18 +242,18 @@ def test_batch_array_ops():
testcheck.check(out.data[3] == double(8.0), "mul_arr[3]==8", "mul_arr[3]==8")
# sqrt array
c: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
c: numpy.ndarray[double]* = numpy.zeros(pool, 4)
c.data[0] = double(4.0)
c.data[1] = double(9.0)
c.data[2] = double(16.0)
c.data[3] = double(25.0)
out4: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
out4: numpy.ndarray[double]* = numpy.zeros(pool, 4)
vipersimd.simd_sqrt_array(c.data, out4.data, sizet(4))
testcheck.check(out4.data[0] == double(2.0), "sqrt_arr[0]==2", "sqrt_arr[0]==2")
testcheck.check(out4.data[3] == double(5.0), "sqrt_arr[3]==5", "sqrt_arr[3]==5")
# abs array
d: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
d: numpy.ndarray[double]* = numpy.zeros(pool, 4)
d.data[0] = double(-1.0)
d.data[1] = double(-2.0)
d.data[2] = double(3.0)
@@ -264,13 +264,13 @@ def test_batch_array_ops():
testcheck.check(out4.data[3] == double(4.0), "abs_arr[3]==4", "abs_arr[3]==4")
# dot array
e: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 4)
e: numpy.ndarray[double]* = numpy.zeros(pool, 4)
e.data[0] = double(1.0)
e.data[1] = double(2.0)
e.data[2] = double(3.0)
e.data[3] = double(4.0)
f: numpy.ndarray[double] | t.CPtr = numpy.ones(pool, 4)
out1: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, 1)
f: numpy.ndarray[double]* = numpy.ones(pool, 4)
out1: numpy.ndarray[double]* = numpy.zeros(pool, 1)
vipersimd.simd_dot_array(e.data, f.data, sizet(4), out1.data)
testcheck.check(out1.data[0] == double(10.0), "dot_arr==10", "dot_arr==10")
@@ -365,53 +365,43 @@ define N_ELEM = 40000
define N_ITER = 50000
def scalar_add_array(a: t.CPtr, b: t.CPtr, out: t.CPtr, n: sizet):
i: sizet = 0
da: double | t.CPtr = a
db: double | t.CPtr = b
dout: double | t.CPtr = out
while i < n:
da: double* = a
db: double* = b
dout: double* = out
for i in range(n):
dout[i] = da[i] + db[i]
i += 1
def scalar_mul_array(a: t.CPtr, b: t.CPtr, out: t.CPtr, n: sizet):
i: sizet = 0
da: double | t.CPtr = a
db: double | t.CPtr = b
dout: double | t.CPtr = out
while i < n:
da: double* = a
db: double* = b
dout: double* = out
for i in range(n):
dout[i] = da[i] * db[i]
i += 1
def scalar_sqrt_array(a: t.CPtr, out: t.CPtr, n: sizet):
i: sizet = 0
da: double | t.CPtr = a
dout: double | t.CPtr = out
while i < n:
da: double* = a
dout: double* = out
for i in range(n):
dout[i] = vipersimd.simd_sqrt(da[i])
i += 1
def benchmark_simd_vs_scalar():
testcheck.section("Benchmark: SIMD vs Scalar")
a: numpy.ndarray[double] | t.CPtr = numpy.full(pool, N_ELEM, double(1.5))
b: numpy.ndarray[double] | t.CPtr = numpy.full(pool, N_ELEM, double(2.5))
out: numpy.ndarray[double] | t.CPtr = numpy.zeros(pool, N_ELEM)
a: numpy.ndarray[double]* = numpy.full(pool, N_ELEM, double(1.5))
b: numpy.ndarray[double]* = numpy.full(pool, N_ELEM, double(2.5))
out: numpy.ndarray[double]* = numpy.zeros(pool, N_ELEM)
# --- SIMD add benchmark ---
t0: t.CLong = clock()
iter: int = 0
while iter < N_ITER:
for iter in range(N_ITER):
vipersimd.simd_add_array(a.data, b.data, out.data, sizet(N_ELEM))
iter += 1
t1: t.CLong = clock()
simd_add_ms: t.CLong = t1 - t0
# --- Scalar add benchmark ---
t0 = clock()
iter = 0
while iter < N_ITER:
for iter in range(N_ITER):
scalar_add_array(a.data, b.data, out.data, sizet(N_ELEM))
iter += 1
t1 = clock()
scalar_add_ms: t.CLong = t1 - t0
@@ -423,19 +413,15 @@ def benchmark_simd_vs_scalar():
# --- SIMD mul benchmark ---
t0 = clock()
iter = 0
while iter < N_ITER:
for iter in range(N_ITER):
vipersimd.simd_mul_array(a.data, b.data, out.data, sizet(N_ELEM))
iter += 1
t1 = clock()
simd_mul_ms: t.CLong = t1 - t0
# --- Scalar mul benchmark ---
t0 = clock()
iter = 0
while iter < N_ITER:
for iter in range(N_ITER):
scalar_mul_array(a.data, b.data, out.data, sizet(N_ELEM))
iter += 1
t1 = clock()
scalar_mul_ms: t.CLong = t1 - t0
@@ -447,19 +433,15 @@ def benchmark_simd_vs_scalar():
# --- SIMD sqrt benchmark ---
t0 = clock()
iter = 0
while iter < N_ITER:
for iter in range(N_ITER):
vipersimd.simd_sqrt_array(a.data, out.data, sizet(N_ELEM))
iter += 1
t1 = clock()
simd_sqrt_ms: t.CLong = t1 - t0
# --- Scalar sqrt benchmark ---
t0 = clock()
iter = 0
while iter < N_ITER:
for iter in range(N_ITER):
scalar_sqrt_array(a.data, out.data, sizet(N_ELEM))
iter += 1
t1 = clock()
scalar_sqrt_ms: t.CLong = t1 - t0
+2 -2
View File
@@ -10,9 +10,9 @@ import ast
class Result:
__slots__ = ('elem_type_node', 'count_node', 'is_pointer')
def __init__(self, elem: ast.AST, count: ast.AST | t.CPtr, flag: bool) -> None:
def __init__(self, elem: ast.AST, count: ast.AST*, flag: bool) -> None:
self.elem_type_node: ast.AST = elem
self.count_node: ast.AST | t.CPtr = count
self.count_node: ast.AST* = count
self.is_pointer: bool = flag
def main() -> int:
+22 -22
View File
@@ -10,8 +10,8 @@ import inline_test
# ============================================================
def test_string_ptr_iter():
testcheck.section("Test 1: string pointer iteration")
s: char | t.CPtr = "Hello"
p: char | t.CPtr = s
s: char* = "Hello"
p: char* = s
count: int = 0
while *p != 0:
count += 1
@@ -23,8 +23,8 @@ def test_string_ptr_iter():
# ============================================================
def test_string_ascii_sum():
testcheck.section("Test 2: string ASCII sum")
s: char | t.CPtr = "ABC"
p: char | t.CPtr = s
s: char* = "ABC"
p: char* = s
total: int = 0
while *p != 0:
total += int(*p)
@@ -37,10 +37,10 @@ def test_string_ascii_sum():
# ============================================================
def test_manual_strcpy():
testcheck.section("Test 3: manual strcpy via pointers")
src: char | t.CPtr = "Test"
src: char* = "Test"
dst: t.CArray[char, 32] = [0]
sp: char | t.CPtr = src
dp: char | t.CPtr = &dst
sp: char* = src
dp: char* = &dst
while *sp != 0:
*dp = *sp
sp += 1
@@ -56,8 +56,8 @@ def test_ptr_offset_compare():
arr: t.CArray[int, 5] = [0]
for i in range(5):
arr[i] = i * 10
p: int | t.CPtr = &arr
start: int | t.CPtr = p
p: int* = &arr
start: int* = p
total: int = 0
while p != start + 5:
total += *p
@@ -69,8 +69,8 @@ def test_ptr_offset_compare():
# ============================================================
def test_manual_strlen():
testcheck.section("Test 5: manual strlen")
s: char | t.CPtr = "Hello World!"
p: char | t.CPtr = s
s: char* = "Hello World!"
p: char* = s
length: sizet = 0
while *p != 0:
length += 1
@@ -82,16 +82,16 @@ def test_manual_strlen():
# ============================================================
def test_reverse_string_ptr():
testcheck.section("Test 6: reverse string via pointer")
src: char | t.CPtr = "abcd"
src: char* = "abcd"
dst: t.CArray[char, 32] = [0]
# Find end of src
p: char | t.CPtr = src
p: char* = src
length: int = 0
while *p != 0:
length += 1
p += 1
# Copy in reverse
dp: char | t.CPtr = &dst
dp: char* = &dst
p = src + length - 1
while p >= src:
*dp = *p
@@ -107,8 +107,8 @@ def test_reverse_string_ptr():
def test_double_pointer():
testcheck.section("Test 7: double pointer")
x: int = 42
px: int | t.CPtr = &x
ppx: int | t.CPtr | t.CPtr = &px
px: int* = &x
ppx: int** = &px
# Read through double pointer
val: int = *(*ppx)
testcheck.check(val == 42, "double pointer (val=42)", "double pointer (val expect 42)")
@@ -121,7 +121,7 @@ def test_ptr_arithmetic():
arr: t.CArray[int, 8] = [0]
for i in range(8):
arr[i] = (i + 1) * (i + 1)
p: int | t.CPtr = &arr
p: int* = &arr
# Access arr[3] via pointer: p + 3
val: int = *(p + 3)
# arr[3] = 4*4 = 16
@@ -132,10 +132,10 @@ def test_ptr_arithmetic():
# ============================================================
def test_manual_strcmp():
testcheck.section("Test 9: manual strcmp via pointers")
s1: char | t.CPtr = "Hello"
s2: char | t.CPtr = "Hello"
p1: char | t.CPtr = s1
p2: char | t.CPtr = s2
s1: char* = "Hello"
s2: char* = "Hello"
p1: char* = s1
p2: char* = s2
equal: int = 1
while *p1 != 0 and *p2 != 0:
if *p1 != *p2:
@@ -159,7 +159,7 @@ def test_struct_ptr_access():
v: Vec2 = Vec2()
v.x = 10
v.y = 20
p: Vec2 | t.CPtr = &v
p: Vec2* = &v
# Modify through pointer
(*p).x = 100
(*p).y = 200
+8 -8
View File
@@ -6,13 +6,13 @@ import w32.win32memory
def test_strlen():
testcheck.section("Test 1: strlen")
s: char | t.CPtr = "Hello, World!"
s: char* = "Hello, World!"
length: uint64 = string.strlen(s)
testcheck.check(length == 13, "strlen (len=13)", "strlen (expect 13)")
def test_strcpy():
testcheck.section("Test 2: strcpy")
buf: char | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 12288, 4)
buf: char* = w32.win32memory.VirtualAlloc(None, 64, 12288, 4)
if uint64(buf) == 0:
stdio.printf("SKIP: VirtualAlloc returned NULL\n")
return
@@ -23,14 +23,14 @@ def test_strcpy():
def test_strcat():
testcheck.section("Test 3: strcat (via memcpy)")
buf: char | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 12288, 4)
buf: char* = w32.win32memory.VirtualAlloc(None, 64, 12288, 4)
if uint64(buf) == 0:
stdio.printf("SKIP: VirtualAlloc returned NULL\n")
return
string.memset(buf, 0, 64)
# 手动拼接: 先拷贝 "Hello",再拷贝 " World"
hello: char | t.CPtr = "Hello"
world: char | t.CPtr = " World"
hello: char* = "Hello"
world: char* = " World"
string.memcpy(buf, hello, 5)
string.memcpy(t.CPtr(uint64(buf) + 5), world, 6)
cmp_result: int = string.strcmp(buf, "Hello World")
@@ -45,7 +45,7 @@ def test_strcmp():
def test_strncpy():
testcheck.section("Test 5: strncpy")
buf: char | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 12288, 4)
buf: char* = w32.win32memory.VirtualAlloc(None, 64, 12288, 4)
if uint64(buf) == 0:
stdio.printf("SKIP: VirtualAlloc returned NULL\n")
return
@@ -56,13 +56,13 @@ def test_strncpy():
def test_char_access():
testcheck.section("Test 6: char access")
s: char | t.CPtr = "ABCDE"
s: char* = "ABCDE"
val: uint8 = s[2] # 'C' = 67
testcheck.check(val == 67, "char access (s[2]=67='C')", "char access (s[2] expect 67)")
def test_snprintf():
testcheck.section("Test 7: snprintf")
buf: char | t.CPtr = w32.win32memory.VirtualAlloc(None, 128, 12288, 4)
buf: char* = w32.win32memory.VirtualAlloc(None, 128, 12288, 4)
if uint64(buf) == 0:
stdio.printf("SKIP: VirtualAlloc returned NULL\n")
return
+3 -3
View File
@@ -38,7 +38,7 @@ def test_struct_pointer():
p.x = 42
p.y = 84
# 取结构体指针
pp: Point | t.CPtr = t.CPtr(uint64(p))
pp: Point* = t.CPtr(uint64(p))
# 通过指针修改
pp.x = 100
pp.y = 200
@@ -59,13 +59,13 @@ def point_sum(p: Point) -> int:
def test_struct_array():
testcheck.section("Test 5: struct array")
# 分配结构体数组
buf: uint8 | t.CPtr = w32.win32memory.VirtualAlloc(None, 256, 12288, 4)
buf: uint8* = w32.win32memory.VirtualAlloc(None, 256, 12288, 4)
if uint64(buf) == 0:
stdio.printf("SKIP: VirtualAlloc returned NULL\n")
return
string.memset(buf, 0, 256)
# 将缓冲区转为 Point 数组
pts: Point | t.CPtr = (Point | t.CPtr)(buf)
pts: Point* = (Point*)(buf)
pts[0].x = 1
pts[0].y = 2
pts[1].x = 3
+1 -1
View File
@@ -24,7 +24,7 @@ def main() -> CInt | CExport:
# 初始化全局 MBuddy 内存分配器
arena: bytes = stdlib.malloc(ARENA_SIZE)
mbuddy_obj: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, ARENA_SIZE)
mbuddy_obj: memhub.MemBuddy* = memhub.MemBuddy(arena, ARENA_SIZE)
# 将 MBuddy 对象赋值给所有需要内存分配的模块
sys._mbuddy = mbuddy_obj
+7 -7
View File
@@ -45,7 +45,7 @@ def _basic_worker(arg: t.CPtr) -> t.CPtr:
# 传参: 通过 arg 指针自增 100 次(c.Deref/c.DerefAs 读写)
def _increment_worker(arg: t.CPtr) -> t.CPtr:
ip: int | t.CPtr = (int | t.CPtr)(arg)
ip: int* = (int*)(arg)
i: int
for i in range(100):
c.DerefAs(ip, *ip + 1)
@@ -54,7 +54,7 @@ def _increment_worker(arg: t.CPtr) -> t.CPtr:
# Lock: 持锁自增全局计数器
def _lock_worker(arg: t.CPtr) -> t.CPtr:
lk: vthreading.Lock | t.CPtr = (vthreading.Lock | t.CPtr)(arg)
lk: vthreading.Lock* = (vthreading.Lock*)(arg)
global _shared_count
for i in range(LOCK_ITER):
lk.acquire()
@@ -65,7 +65,7 @@ def _lock_worker(arg: t.CPtr) -> t.CPtr:
# Event: 等待事件被唤醒后置位完成标志
def _event_worker(arg: t.CPtr) -> t.CPtr:
ev: vthreading.Event | t.CPtr = (vthreading.Event | t.CPtr)(arg)
ev: vthreading.Event* = (vthreading.Event*)(arg)
global _evt_done
r: int = ev.wait(5000)
if r == 1:
@@ -75,7 +75,7 @@ def _event_worker(arg: t.CPtr) -> t.CPtr:
# Condition 消费者: 循环等待 _cond_ready 就绪(限次防挂起)
def _cond_consumer(arg: t.CPtr) -> t.CPtr:
cond: vthreading.Condition | t.CPtr = (vthreading.Condition | t.CPtr)(arg)
cond: vthreading.Condition* = (vthreading.Condition*)(arg)
global _cond_ready
tries: int = 0
cond.acquire()
@@ -88,7 +88,7 @@ def _cond_consumer(arg: t.CPtr) -> t.CPtr:
# Condition 生产者: 延迟后置位 _cond_ready 并 notify
def _cond_producer(arg: t.CPtr) -> t.CPtr:
cond: vthreading.Condition | t.CPtr = (vthreading.Condition | t.CPtr)(arg)
cond: vthreading.Condition* = (vthreading.Condition*)(arg)
global _cond_ready
vthreading.sleep_ms(50)
cond.acquire()
@@ -100,7 +100,7 @@ def _cond_producer(arg: t.CPtr) -> t.CPtr:
# RWLock 读者: 持读锁反复读共享值
def _rw_reader(arg: t.CPtr) -> t.CPtr:
rwl: vthreading.RWLock | t.CPtr = (vthreading.RWLock | t.CPtr)(arg)
rwl: vthreading.RWLock* = (vthreading.RWLock*)(arg)
global _rw_value
i: int
for i in range(RW_ITER * 10):
@@ -112,7 +112,7 @@ def _rw_reader(arg: t.CPtr) -> t.CPtr:
# RWLock 写者: 持写锁自增共享值
def _rw_writer(arg: t.CPtr) -> t.CPtr:
rwl: vthreading.RWLock | t.CPtr = (vthreading.RWLock | t.CPtr)(arg)
rwl: vthreading.RWLock* = (vthreading.RWLock*)(arg)
global _rw_value
i: int
for i in range(RW_ITER):
+2 -2
View File
@@ -120,7 +120,7 @@ def test_comparison_types():
# --- Test 12: 指针与整数互转 ---
def test_ptr_int_cast():
buf: uint32 | t.CPtr = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
buf: uint32* = w32.win32memory.VirtualAlloc(None, 64, 0x3000, 0x04)
if not buf:
testcheck.fail("VirtualAlloc returned NULL")
return
@@ -128,7 +128,7 @@ def test_ptr_int_cast():
addr: uint64 = uint64(buf)
stdio.printf(" ptr->int: addr=0x%lx\n", addr)
# 整数转指针
p2: uint32 | t.CPtr = (uint32 | t.CPtr)(addr)
p2: uint32* = (uint32*)(addr)
p2[0] = 0x12345678
testcheck.check(buf[0] == 0x12345678, "ptr<->int roundtrip", "ptr<->int roundtrip failed")
+1 -1
View File
@@ -8,7 +8,7 @@ import requests
# 全局 MBuddy 指针
_mbuddy: memhub.MemBuddy | t.CPtr
_mbuddy: memhub.MemBuddy*
@t.CExport
+9 -9
View File
@@ -141,7 +141,7 @@ def test_compressobj():
out_length: sizet = 0
s: pyzlib.Compress | t.CPtr = pyzlib.compressobj(None, pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.DEFLATED,
s: pyzlib.Compress* = pyzlib.compressobj(None, pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.DEFLATED,
pyzlib.MAX_WBITS, pyzlib.DEF_MEM_LEVEL,
pyzlib.Z_DEFAULT_STRATEGY, None, 0)
check("compressobj created", s != None, "compressobj is None")
@@ -212,7 +212,7 @@ def test_decompressobj():
pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.MAX_WBITS, &out_length)
printf(" Compressed: %zu bytes\n", out_length)
d: pyzlib.Decompress | t.CPtr = pyzlib.decompressobj(None, pyzlib.MAX_WBITS, None, 0)
d: pyzlib.Decompress* = pyzlib.decompressobj(None, pyzlib.MAX_WBITS, None, 0)
check("decompressobj created", d != None, "decompressobj is None")
check("eof is false initially", d.eof == 0, "eof should be 0")
print_separator()
@@ -246,7 +246,7 @@ def test_decompressobj_max_length():
pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.MAX_WBITS, &out_length)
printf(" Compressed: %zu bytes\n", out_length)
d: pyzlib.Decompress | t.CPtr = pyzlib.decompressobj(None, pyzlib.MAX_WBITS, None, 0)
d: pyzlib.Decompress* = pyzlib.decompressobj(None, pyzlib.MAX_WBITS, None, 0)
dec_length: sizet = 0
dec: BYTEPTR = d.decompress(compressed, out_length,
@@ -295,7 +295,7 @@ def test_decompressobj_unused_data():
stdlib.free(compressed)
printf(" Combined (compressed + \"EXTRA\"): %zu bytes\n", total_length)
d: pyzlib.Decompress | t.CPtr = pyzlib.decompressobj(None, pyzlib.MAX_WBITS, None, 0)
d: pyzlib.Decompress* = pyzlib.decompressobj(None, pyzlib.MAX_WBITS, None, 0)
dec_length: sizet = 0
dec: BYTEPTR = d.decompress(combined, total_length,
@@ -327,13 +327,13 @@ def test_compress_copy():
printf(" Input: \"%s\"\n", inp)
out_length: sizet = 0
c1: pyzlib.Compress | t.CPtr = pyzlib.compressobj(None, pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.DEFLATED,
c1: pyzlib.Compress* = pyzlib.compressobj(None, pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.DEFLATED,
pyzlib.MAX_WBITS, pyzlib.DEF_MEM_LEVEL,
pyzlib.Z_DEFAULT_STRATEGY, None, 0)
c1.compress(BYTEPTR(inp), input_length, &out_length)
printf(" Original: compressed %zu bytes so far\n", out_length)
c2: pyzlib.Compress | t.CPtr = c1.copy()
c2: pyzlib.Compress* = c1.copy()
check("compress copy OK", c2 != None, "copy returned None")
printf(" Copied compressobj\n")
@@ -370,8 +370,8 @@ def test_decompress_copy():
pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.MAX_WBITS, &out_length)
printf(" Compressed: %zu bytes\n", out_length)
d1: pyzlib.Decompress | t.CPtr = pyzlib.decompressobj(None, pyzlib.MAX_WBITS, None, 0)
d2: pyzlib.Decompress | t.CPtr = d1.copy()
d1: pyzlib.Decompress* = pyzlib.decompressobj(None, pyzlib.MAX_WBITS, None, 0)
d2: pyzlib.Decompress* = d1.copy()
check("decompress copy OK", d2 != None, "copy returned None")
printf(" Copied decompressobj\n")
@@ -526,7 +526,7 @@ def test_zdict():
printf(" Input : \"%s\" (%zu bytes)\n", inp, input_length)
out_length: sizet = 0
s: pyzlib.Compress | t.CPtr = pyzlib.compressobj(None, pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.DEFLATED,
s: pyzlib.Compress* = pyzlib.compressobj(None, pyzlib.Z_DEFAULT_COMPRESSION, pyzlib.DEFLATED,
pyzlib.MAX_WBITS, pyzlib.DEF_MEM_LEVEL,
pyzlib.Z_DEFAULT_STRATEGY,
BYTEPTR(dict), strlen(dict))