去除 import t, c

This commit is contained in:
TermiNexus committed 2026-10-17 21:57:03 +08:00
1 parent 579cf8d8e0
commit e67b80c083
112 files changed
+1235 -1347

No files matched your search

+1 -3
View File
@@ -1,4 +1,3 @@
import t, c
from stdint import *
import stdio
import stdlib
@@ -12,8 +11,7 @@ import testcheck
_mbuddy: memhub.MemBuddy*
@t.CExport
def main() -> int:
export def main() -> int:
global _mbuddy
testcheck.begin("ArgparseTest: 命令行参数解析")
+1 -3
View File
@@ -1,6 +1,4 @@
from stdint import *
import t, c
from t import CInt, CExport
from stdio import printf
import memhub
import stdlib
@@ -93,7 +91,7 @@ def classify_print(node: ast.AST*, depth: int):
classify_print(node.children.get(i), depth + 1)
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
+1 -3
View File
@@ -1,12 +1,10 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CExport
import memhub
import mbuddytest
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
+75 -77
View File
@@ -1,5 +1,3 @@
import t, c
from t import CInt, CPtr, CChar, CUInt8T, CUInt32T, CUInt64T, CSizeT
import viperlib
import viperio
import stdlib
@@ -12,19 +10,19 @@ import win32.win32base
# Thread body: alloc/free on a shared MBuddy to exercise the spinlock
def _thread_alloc_free(param: t.CPtr) -> uint32:
def _thread_alloc_free(param: rawptr) -> uint32:
bd: memhub.MemBuddy* = (memhub.MemBuddy*)(param)
i: CInt
i: int
for i in range(100):
p: bytes = bd.alloc(32)
if p != None:
p_c: CUInt8T | CPtr = CPtr(p)
p_c[0] = CUInt8T(i & 0xFF)
p_c: uint8* = uint8*(p)
p_c[0] = uint8(i & 0xFF)
bd.free(p)
return 0
def mbuddy_main() -> CInt:
def mbuddy_main() -> int:
buf: bytes = stdlib.malloc(256)
testcheck.begin("BuddyTest: 伙伴系统内存分配器测试")
@@ -32,7 +30,7 @@ def mbuddy_main() -> CInt:
# === Basic alloc/free ===
testcheck.section("基础 alloc/free")
arena: bytes = stdlib.malloc(65536)
bd: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena, 65536)
bd: memhub.MemBuddy* = memhub.MemBuddy(arena, 65536)
viperlib.snprintf(buf, 256, "stats=%lu, free_count=%lu", bd.stats(), bd.free_count())
testcheck.info(buf)
@@ -44,12 +42,12 @@ def mbuddy_main() -> CInt:
"3 allocs OK", "alloc FAILED")
# Write data to verify the returned pointer is usable
p_c: CUInt8T | CPtr = CPtr(p1)
p_c[0] = CUInt8T(0xAB)
p_c[1] = CUInt8T(0xCD)
p_c: uint8* = uint8*(p1)
p_c[0] = uint8(0xAB)
p_c[1] = uint8(0xCD)
viperlib.snprintf(buf, 256, "p1[0]=0x%x p1[1]=0x%x", p_c[0], p_c[1])
testcheck.info(buf)
testcheck.check(p_c[0] == CUInt8T(0xAB) and p_c[1] == CUInt8T(0xCD),
testcheck.check(p_c[0] == uint8(0xAB) and p_c[1] == uint8(0xCD),
"write/read OK", "write/read FAILED")
bd.free(p1)
@@ -74,24 +72,24 @@ def mbuddy_main() -> CInt:
arena2: bytes = stdlib.malloc(4096)
viperlib.snprintf(buf, 256, "arena2 = %p", arena2)
testcheck.info(buf)
bd2: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena2, 4096)
bd2: memhub.MemBuddy* = memhub.MemBuddy(arena2, 4096)
dirty: bytes = bd2.alloc(64)
viperlib.snprintf(buf, 256, "dirty = %p", dirty)
testcheck.info(buf)
d_c: CUInt8T | CPtr = CPtr(dirty)
i: CInt
d_c: uint8* = uint8*(dirty)
i: int
for i in range(64):
d_c[i] = CUInt8T(0xFF)
d_c[i] = uint8(0xFF)
bd2.free(dirty)
cl: bytes = bd2.calloc(8, 8)
viperlib.snprintf(buf, 256, "cl = %p (arena2=%p, dirty was=%p)", cl, arena2, dirty)
testcheck.info(buf)
if cl != None:
cl_c: CUInt8T | CPtr = CPtr(cl)
all_zero: CInt = 1
j: CInt
cl_c: uint8* = uint8*(cl)
all_zero: int = 1
j: int
for j in range(64):
if cl_c[j] != 0:
all_zero = 0
@@ -106,21 +104,21 @@ def mbuddy_main() -> CInt:
# === realloc grow ===
testcheck.section("realloc 扩展")
arena3: bytes = stdlib.malloc(4096)
bd3: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena3, 4096)
bd3: memhub.MemBuddy* = memhub.MemBuddy(arena3, 4096)
rp: bytes = bd3.alloc(32)
rp_c: CUInt8T | CPtr = CPtr(rp)
k: CInt
rp_c: uint8* = uint8*(rp)
k: int
for k in range(32):
rp_c[k] = CUInt8T(k + 1)
rp_c[k] = uint8(k + 1)
rp2: bytes = bd3.realloc(rp, 128)
if rp2 != None:
rp2_c: CUInt8T | CPtr = CPtr(rp2)
ok: CInt = 1
m: CInt
rp2_c: uint8* = uint8*(rp2)
ok: int = 1
m: int
for m in range(32):
if rp2_c[m] != CUInt8T(m + 1):
if rp2_c[m] != uint8(m + 1):
ok = 0
break
testcheck.check(ok == 1, "realloc grow data preserved OK", "realloc grow data LOST")
@@ -133,24 +131,24 @@ def mbuddy_main() -> CInt:
# === in-place shrink (verify no leak) ===
testcheck.section("原地收缩 (realloc shrink)")
arena_shrink: bytes = stdlib.malloc(4096)
bds: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_shrink, 4096)
bds: memhub.MemBuddy* = memhub.MemBuddy(arena_shrink, 4096)
sp: bytes = bds.alloc(256)
testcheck.check(sp != None, "alloc 256 OK", "alloc 256 FAILED")
fc_before: CSizeT = bds.free_count()
fc_before: sizet = bds.free_count()
# Shrink 256 -> 32: order 4 (264) to order 1 (40); since new order <= old,
# realloc must return the same pointer in place
sp2: bytes = bds.realloc(sp, 32)
fc_after: CSizeT = bds.free_count()
fc_after: sizet = bds.free_count()
testcheck.check(sp2 == sp, "shrink same ptr OK", "shrink ptr changed")
testcheck.check(fc_after == fc_before, "shrink no leak OK", "shrink LEAKED blocks")
# Data must remain readable/writable after shrink
sp_c: CUInt8T | CPtr = CPtr(sp2)
sp_c[0] = CUInt8T(0x42)
testcheck.check(sp_c[0] == CUInt8T(0x42), "shrink data OK", "shrink data FAILED")
sp_c: uint8* = uint8*(sp2)
sp_c[0] = uint8(0x42)
testcheck.check(sp_c[0] == uint8(0x42), "shrink data OK", "shrink data FAILED")
bds.free(sp2)
testcheck.check(bds.free_count() == 6, "shrink+free coalesce OK", "shrink+free coalesce FAILED")
@@ -160,7 +158,7 @@ def mbuddy_main() -> CInt:
# === Edge cases ===
testcheck.section("边界情况")
arena4: bytes = stdlib.malloc(4096)
bd4: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena4, 4096)
bd4: memhub.MemBuddy* = memhub.MemBuddy(arena4, 4096)
# alloc(0) must return None
z: bytes = bd4.alloc(0)
@@ -185,13 +183,13 @@ def mbuddy_main() -> CInt:
# === Illegal pointer defense ===
testcheck.section("非法指针防护")
arena5: bytes = stdlib.malloc(4096)
bd5: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena5, 4096)
bd5: memhub.MemBuddy* = memhub.MemBuddy(arena5, 4096)
valid: bytes = bd5.alloc(32)
testcheck.check(valid != None, "alloc for illegal test OK", "alloc FAILED")
# 1. free a random address (address 1)
bd5.free(t.CPtr(uint64(1)))
bd5.free(rawptr(uint64(1)))
testcheck.ok("free(addr=1) ignored")
# 2. free NULL
@@ -199,15 +197,15 @@ def mbuddy_main() -> CInt:
testcheck.ok("free(NULL) ignored")
# 3. free an out-of-range pointer (before arena)
bd5.free(t.CPtr(uint64(arena5)))
bd5.free(rawptr(uint64(arena5)))
testcheck.ok("free(before arena) ignored")
# 4. free an out-of-range pointer (after arena)
bd5.free(t.CPtr(uint64(arena5) + 99999))
bd5.free(rawptr(uint64(arena5) + 99999))
testcheck.ok("free(after arena) ignored")
# 5. free a misaligned pointer (inside mem but not aligned)
bd5.free(t.CPtr(uint64(bd5.base) + 1))
bd5.free(rawptr(uint64(bd5.base) + 1))
testcheck.ok("free(misaligned) ignored")
# 6. a valid free must still work (block reusable after)
@@ -218,7 +216,7 @@ def mbuddy_main() -> CInt:
bd5.free(retry5)
# 7. realloc on an illegal pointer must return None
r_illegal: bytes = bd5.realloc(t.CPtr(1), 64)
r_illegal: bytes = bd5.realloc(rawptr(1), 64)
testcheck.check(r_illegal == None, "realloc(illegal)=None OK", "realloc(illegal) should be None")
stdlib.free(arena5)
@@ -226,12 +224,12 @@ def mbuddy_main() -> CInt:
# === OOM exhaustion ===
testcheck.section("OOM 内存耗尽")
arena6: bytes = stdlib.malloc(4096)
bd6: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena6, 4096)
bd6: memhub.MemBuddy* = memhub.MemBuddy(arena6, 4096)
# Allocate until failure
alloc_count: CInt = 0
alloc_count: int = 0
ptrs_arr: bytes = stdlib.malloc(8 * 256) # Pointer storage array
ptrs: CUInt64T | CPtr = CPtr(ptrs_arr)
ptrs: uint64* = uint64*(ptrs_arr)
while alloc_count < 256:
p: bytes = bd6.alloc(32)
@@ -250,7 +248,7 @@ def mbuddy_main() -> CInt:
# After freeing one block, allocation must succeed again
if alloc_count > 0:
first_ptr: bytes = t.CPtr(ptrs[0])
first_ptr: bytes = rawptr(ptrs[0])
bd6.free(first_ptr)
retry: bytes = bd6.alloc(32)
testcheck.check(retry != None, "OOM: free+alloc OK", "OOM: free+alloc FAILED")
@@ -259,7 +257,7 @@ def mbuddy_main() -> CInt:
# Free all blocks
for idx in range(1, alloc_count):
cur_p: bytes = t.CPtr(ptrs[idx])
cur_p: bytes = rawptr(ptrs[idx])
bd6.free(cur_p)
# Full free must coalesce back to the initial 6 blocks
@@ -272,26 +270,26 @@ def mbuddy_main() -> CInt:
# === Free-list state ===
testcheck.section("空闲链表状态")
arena7: bytes = stdlib.malloc(4096)
bd7: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena7, 4096)
bd7: memhub.MemBuddy* = memhub.MemBuddy(arena7, 4096)
# Initial: non-power-of-two arena (4096 - 264 = 3832) splits into 6 blocks
testcheck.check(bd7.free_count() == 6, "init: 6 free blocks OK", "init: free_count != 6")
# After alloc: free count grows because a block is split
a1: bytes = bd7.alloc(32)
fc1: CSizeT = bd7.free_count()
fc1: sizet = bd7.free_count()
viperlib.snprintf(buf, 256, "after alloc(32): free_count=%lu", fc1)
testcheck.info(buf)
testcheck.check(fc1 > 1, "after alloc: split OK", "after alloc: no split")
# Second alloc
a2: bytes = bd7.alloc(32)
fc2: CSizeT = bd7.free_count()
fc2: sizet = bd7.free_count()
testcheck.check(fc2 >= 1, "after 2nd alloc: free >= 1 OK", "after 2nd alloc: free < 1")
# Free a1: free count must increase
bd7.free(a1)
fc3: CSizeT = bd7.free_count()
fc3: sizet = bd7.free_count()
testcheck.check(fc3 > fc2, "after free a1: free increased OK", "after free a1: free not increased")
# Free a2: coalescing must restore the initial 6 blocks
@@ -321,19 +319,19 @@ def mbuddy_main() -> CInt:
# === Double-free detection ===
testcheck.section("双重 free 检测")
arena_df: bytes = stdlib.malloc(4096)
bd_df: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_df, 4096)
bd_df: memhub.MemBuddy* = memhub.MemBuddy(arena_df, 4096)
df: bytes = bd_df.alloc(64)
testcheck.check(df != None, "df: alloc OK", "df: alloc FAILED")
# First free
bd_df.free(df)
fc_df1: CSizeT = bd_df.free_count()
fc_df1: sizet = bd_df.free_count()
testcheck.ok("first free OK")
# Second free (double free): must be silently rejected
bd_df.free(df)
fc_df2: CSizeT = bd_df.free_count()
fc_df2: sizet = bd_df.free_count()
testcheck.check(fc_df2 == fc_df1, "double free rejected OK", "double free CORRUPTED state")
# Allocator must still be functional
@@ -347,7 +345,7 @@ def mbuddy_main() -> CInt:
# === Self-check ===
testcheck.section("自检功能")
arena_sc: bytes = stdlib.malloc(4096)
bd_sc: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_sc, 4096)
bd_sc: memhub.MemBuddy* = memhub.MemBuddy(arena_sc, 4096)
# Self-check on initial state
testcheck.check(bd_sc.self_check() == 0, "self_check init OK", "self_check init FAILED")
@@ -376,22 +374,22 @@ def mbuddy_main() -> CInt:
# === Concurrent threads (spinlock) ===
testcheck.section("并发多线程 (spinlock)")
arena_mt: bytes = stdlib.malloc(65536)
bd_mt: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_mt, 65536)
bd_mt: memhub.MemBuddy* = memhub.MemBuddy(arena_mt, 65536)
NUM_THREADS: CInt = 4
NUM_THREADS: int = 4
handles_arr: bytes = stdlib.malloc(8 * 4)
handles: CUInt64T | CPtr = CPtr(handles_arr)
tid: CUInt32T = 0
handles: uint64* = uint64*(handles_arr)
tid: uint32 = 0
# Spawn 4 threads doing concurrent alloc/free
t_idx: CInt
t_idx: int
for t_idx in range(NUM_THREADS):
h: bytes = win32.win32process.CreateThread(None, 0, _thread_alloc_free, t.CPtr(bd_mt), 0, &tid)
handles[t_idx] = CUInt64T(h)
h: bytes = win32.win32process.CreateThread(None, 0, _thread_alloc_free, rawptr(bd_mt), 0, &tid)
handles[t_idx] = uint64(h)
# Wait for all threads to finish
for t_idx in range(NUM_THREADS):
h: bytes = t.CPtr(handles[t_idx])
h: bytes = rawptr(handles[t_idx])
win32.win32sync.WaitForSingleObject(h, win32.win32base.INFINITE)
win32.win32base.CloseHandle(h)
@@ -410,7 +408,7 @@ def mbuddy_main() -> CInt:
# 1. Alloc size exactly at a block boundary
arena_ex: bytes = stdlib.malloc(4096)
bd_ex: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_ex, 4096)
bd_ex: memhub.MemBuddy* = memhub.MemBuddy(arena_ex, 4096)
# 24 + 16 = 40 > 32 (8 header + 8 sentinel), needs order 1 (64 bytes)
exact_fit: bytes = bd_ex.alloc(24)
@@ -426,7 +424,7 @@ def mbuddy_main() -> CInt:
# 2. Alloc near the largest block limit (order6 = 2048): usable = 2048 - 16,
# so alloc(max_usable) exactly fills one order6 block
max_usable: CSizeT = 2048 - 16
max_usable: sizet = 2048 - 16
viperlib.snprintf(buf, 256, "mem_size=%lu, max_block=2048, max_usable=%lu", bd_ex.mem_size, max_usable)
testcheck.info(buf)
@@ -454,7 +452,7 @@ def mbuddy_main() -> CInt:
# 4. Arena too small (only fits the 264-byte free-list overhead)
arena_tiny: bytes = stdlib.malloc(264)
bd_tiny: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_tiny, 264)
bd_tiny: memhub.MemBuddy* = memhub.MemBuddy(arena_tiny, 264)
testcheck.check(bd_tiny.stats() == 0, "tiny arena: stats=0 OK", "tiny arena: stats != 0")
tiny_p: bytes = bd_tiny.alloc(32)
testcheck.check(tiny_p == None, "tiny arena: alloc fails OK", "tiny arena: should fail")
@@ -462,7 +460,7 @@ def mbuddy_main() -> CInt:
# 5. Arena fits exactly one minimal block (264 + 32 = 296)
arena_one: bytes = stdlib.malloc(296)
bd_one: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_one, 296)
bd_one: memhub.MemBuddy* = memhub.MemBuddy(arena_one, 296)
testcheck.check(bd_one.stats() == 32, "one block: stats=32 OK", "one block: stats != 32")
# Minimal block 32 = data 16 + header 8 + sentinel 8; alloc(16) fills it
@@ -478,27 +476,27 @@ def mbuddy_main() -> CInt:
# 6. Power-of-two vs non-power-of-two arena
arena_pow2: bytes = stdlib.malloc(512)
bd_pow2: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_pow2, 512)
bd_pow2: memhub.MemBuddy* = memhub.MemBuddy(arena_pow2, 512)
# 512 - 264 = 248, decomposes to 128 + 64 + 32 = 224 (24-byte tail dropped)
testcheck.check(bd_pow2.stats() == 224, "pow2 arena: stats=224 OK", "pow2 arena: stats != 224")
stdlib.free(arena_pow2)
arena_non2: bytes = stdlib.malloc(500)
bd_non2: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_non2, 500)
bd_non2: memhub.MemBuddy* = memhub.MemBuddy(arena_non2, 500)
# 500 - 264 = 236, decomposes to 128 + 64 + 32 = 224 (12-byte tail dropped)
testcheck.check(bd_non2.stats() == 224, "non-pow2 arena: stats=224 OK", "non-pow2 arena: stats != 224")
stdlib.free(arena_non2)
# 7. Stress: 1000 alloc/free cycles of the same size
arena_stress: bytes = stdlib.malloc(4096)
bd_stress: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_stress, 4096)
bd_stress: memhub.MemBuddy* = memhub.MemBuddy(arena_stress, 4096)
s: CInt
s: int
for s in range(1000):
sp: bytes = bd_stress.alloc(64)
if sp != None:
sp_c: CUInt8T | CPtr = CPtr(sp)
sp_c[0] = CUInt8T(s & 0xFF)
sp_c: uint8* = uint8*(sp)
sp_c[0] = uint8(s & 0xFF)
bd_stress.free(sp)
testcheck.check(bd_stress.self_check() == 0, "stress: self_check OK", "stress: self_check FAILED")
@@ -507,13 +505,13 @@ def mbuddy_main() -> CInt:
# 8. Allocate all minimal blocks, then free them all
arena_fill: bytes = stdlib.malloc(4096)
bd_fill: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena_fill, 4096)
bd_fill: memhub.MemBuddy* = memhub.MemBuddy(arena_fill, 4096)
fill_count: CInt = 0
fill_count: int = 0
fill_ptrs_arr: bytes = stdlib.malloc(8 * 256)
fill_ptrs: CUInt64T | CPtr = CPtr(fill_ptrs_arr)
fill_ptrs: uint64* = uint64*(fill_ptrs_arr)
fc: CInt
fc: int
for fc in range(256):
fp: bytes = bd_fill.alloc(24)
if fp == None:
@@ -527,9 +525,9 @@ def mbuddy_main() -> CInt:
testcheck.check(bd_fill.self_check() == 0, "fill: self_check OK", "fill: self_check FAILED")
# Free all
fi: CInt
fi: int
for fi in range(fill_count):
fp2: bytes = t.CPtr(fill_ptrs[fi])
fp2: bytes = rawptr(fill_ptrs[fi])
bd_fill.free(fp2)
testcheck.check(bd_fill.free_count() == 6, "fill: all freed OK", "fill: leaked after free all")
+15 -19
View File
@@ -1,4 +1,3 @@
import t
from stdint import *
from stdio import printf
from stdlib import malloc
@@ -12,8 +11,8 @@ class Rect:
width: int
height: int
def __new__(self, w: int, h: int) -> 'Rect' | t.CPtr:
return t.CPtr(malloc(Rect.__sizeof__()))
def __new__(self, w: int, h: int) -> Rect*:
return malloc(Rect.__sizeof__())
def __init__(self, w: int, h: int):
self.width = w
@@ -44,8 +43,8 @@ def test_property_getter():
class Temperature:
_celsius: double
def __new__(self, celsius_val: double) -> 'Temperature' | t.CPtr:
return t.CPtr(malloc(Temperature.__sizeof__()))
def __new__(self, celsius_val: double) -> Temperature*:
return malloc(Temperature.__sizeof__())
def __init__(self, celsius_val: double):
self._celsius = celsius_val
@@ -78,8 +77,8 @@ def test_property_setter():
class Counter:
_count: int
def __new__(self) -> 'Counter' | t.CPtr:
return t.CPtr(malloc(Counter.__sizeof__()))
def __new__(self) -> Counter*:
return malloc(Counter.__sizeof__())
def __init__(self):
self._count = 0
@@ -108,8 +107,8 @@ class Config:
_value: int
_deleted: int
def __new__(self, v: int) -> 'Config' | t.CPtr:
return t.CPtr(malloc(Config.__sizeof__()))
def __new__(self, v: int) -> Config*:
return malloc(Config.__sizeof__())
def __init__(self, v: int):
self._value = v
@@ -169,19 +168,19 @@ class Point:
x: double
y: double
def __new__(self, x: double, y: double) -> 'Point' | t.CPtr:
return t.CPtr(malloc(Point.__sizeof__()))
def __new__(self, x: double, y: double) -> Point*:
return malloc(Point.__sizeof__())
def __init__(self, x: double, y: double):
self.x = x
self.y = y
@classmethod
def origin(cls: Point) -> Point:
def origin(cls: Point) -> Point*:
return Point(0.0, 0.0)
@classmethod
def from_int(cls: Point, x: int, y: int) -> Point:
def from_int(cls: Point, x: int, y: int) -> Point*:
return Point(x * 1.0, y * 1.0)
def dist_sq(self) -> double:
@@ -208,8 +207,8 @@ def test_classmethod():
class Circle:
_radius: double
def __new__(self, r: double) -> 'Circle' | t.CPtr:
return t.CPtr(malloc(Circle.__sizeof__()))
def __new__(self, r: double) -> Circle*:
return malloc(Circle.__sizeof__())
def __init__(self, r: double):
self._radius = r
@@ -251,10 +250,7 @@ def test_combined():
testcheck.check(not Circle.is_unit(2.0), "not is_unit(2.0)", "is_unit(2.0) should be false")
# ============================================================
# main
# ============================================================
def main() -> int | t.CExport:
export def main() -> int:
testcheck.begin("Builtin Decorator Test")
test_property_getter()
+147 -147
View File
@@ -1,10 +1,10 @@
import t, c
from stdlib import malloc, free
# --- PyObject: base class of all Python objects ---
class PyObject:
ob_refcnt: t.CLong
ob_type: t.CPtr
ob_refcnt: long
ob_type: rawptr
# --- Reference counting ---
@@ -43,7 +43,7 @@ class PyPreConfig:
class PyWideStringList:
length: sizet
items: t.CPtr
items: rawptr
class PyConfig:
_config_version: int
@@ -53,7 +53,7 @@ class PyConfig:
dev_mode: int
install_signal_handlers: int
use_hash_seed: int
hash_seed: t.CUnsignedLong
hash_seed: ulong
faulthandler: int
tracemalloc: int
import_time: int
@@ -101,18 +101,18 @@ extern def PyStatus_Exception(status: PySTATUS) -> int
# --- Integer ops (PyLong) ---
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_FromUnsignedLong(v: ulong) -> PyObject*
extern def PyLong_FromLongLong(v: long) -> PyObject*
extern def PyLong_FromUnsignedLongLong(v: ulong) -> PyObject*
extern def PyLong_FromSsize_t(v: ptrdifft) -> 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.CLongLong
extern def PyLong_AsUnsignedLongLong(obj: PyObject*) -> t.CUnsignedLongLong
extern def PyLong_AsUnsignedLong(obj: PyObject*) -> ulong
extern def PyLong_AsLongLong(obj: PyObject*) -> longlong
extern def PyLong_AsUnsignedLongLong(obj: PyObject*) -> ulonglong
extern def PyLong_AsDouble(obj: PyObject*) -> double
extern def PyLong_AsSsize_t(obj: PyObject*) -> t.CPtrDiffT
extern def PyLong_AsSsize_t(obj: PyObject*) -> ptrdifft
extern def PyLong_AsSize_t(obj: PyObject*) -> sizet
@@ -127,16 +127,16 @@ 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_AsUTF8AndSize(obj: PyObject*, size: ptrdifft*) -> str
extern def PyUnicode_AsWideChar(obj: PyObject*, wbuf: rawptr, bufsize: sizet) -> sizet
extern def PyUnicode_GetLength(obj: PyObject*) -> ptrdifft
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_InternInPlace(s: PyObject**)
extern def PyUnicode_InternFromString(u: const str) -> PyObject*
extern def PyBytes_FromString(v: const str) -> PyObject*
@@ -148,11 +148,11 @@ extern def PyBytes_FromFormat(fmt: const str) -> PyObject*
# --- Bool / None ---
extern def PyBool_FromLong(v: t.CLong) -> PyObject*
extern def PyBool_FromLong(v: long) -> PyObject*
Py_True: PyObject | t.CPtr | t.State
Py_False: PyObject | t.CPtr | t.State
Py_None: PyObject | t.CPtr | t.State
extern Py_True: PyObject*
extern Py_False: PyObject*
extern Py_None: PyObject*
# --- List ops (PyList) ---
@@ -191,9 +191,9 @@ 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_Clear(d: PyObject*)
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_Next(d: PyObject*, pos: ptrdifft*, 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
@@ -220,7 +220,7 @@ 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.CPtrDiffT
extern def PyObject_Hash(obj: PyObject*) -> ptrdifft
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
@@ -231,12 +231,12 @@ extern def PyIter_Next(obj: PyObject*) -> PyObject*
# --- Comparison constants ---
Py_LT: int | t.State
Py_LE: int | t.State
Py_EQ: int | t.State
Py_NE: int | t.State
Py_GT: int | t.State
Py_GE: int | t.State
extern Py_LT: int
extern Py_LE: int
extern Py_EQ: int
extern Py_NE: int
extern Py_GT: int
extern Py_GE: int
# --- Module ops ---
@@ -252,13 +252,13 @@ extern def PyImport_ImportModuleEx(name: const str, globs: PyObject*, locs: PyOb
# --- Module creation ---
class PyMethodDef:
ml_name: const str
ml_meth: t.CPtr
ml_meth: rawptr
ml_flags: int
ml_doc: const str
class PyModuleDef_Base:
ob_base: PyObject
m_init: t.CPtr
m_init: rawptr
m_index: sizet
m_copy: PyObject*
@@ -266,12 +266,12 @@ class PyModuleDef:
m_base: PyModuleDef_Base
m_name: const str
m_doc: const str
m_size: t.CPtrDiffT
m_size: ptrdifft
m_methods: PyMethodDef*
m_slots: t.CPtr
m_traverse: t.CPtr
m_clear: t.CPtr
m_free: t.CPtr
m_slots: rawptr
m_traverse: rawptr
m_clear: rawptr
m_free: rawptr
extern def PyModule_Create(mod: PyModuleDef*) -> PyObject*
extern def PyModule_Create2(mod: PyModuleDef*, ver: int) -> PyObject*
@@ -280,66 +280,66 @@ 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_AddIntConstant(mod: PyObject*, name: const str, val: long) -> int
extern def PyModule_AddStringConstant(mod: PyObject*, name: const str, val: const str) -> int
# --- GIL management ---
extern def PyGILState_Ensure() -> int
extern def PyGILState_Release(state: int): pass
extern def PyEval_SaveThread() -> t.CPtr
extern def PyEval_RestoreThread(tstate: t.CPtr): pass
extern def PyEval_AcquireThread(tstate: t.CPtr): pass
extern def PyEval_ReleaseThread(tstate: t.CPtr): pass
extern def PyEval_AcquireLock(): pass
extern def PyEval_ReleaseLock(): pass
extern def PyGILState_Release(state: int)
extern def PyEval_SaveThread() -> rawptr
extern def PyEval_RestoreThread(tstate: rawptr)
extern def PyEval_AcquireThread(tstate: rawptr)
extern def PyEval_ReleaseThread(tstate: rawptr)
extern def PyEval_AcquireLock()
extern def PyEval_ReleaseLock()
extern def PyEval_ThreadsInitialized() -> int
extern def PyEval_InitThreads(): pass
extern def PyEval_InitThreads()
# --- Error handling ---
extern def PyErr_Occurred() -> PyObject*
extern def PyErr_Clear(): 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*) -> int | t.State: pass
extern def PyErr_GivenExceptionMatches(given: PyObject*, exc: PyObject*) -> int | t.State: pass
extern def PyErr_Clear()
extern def PyErr_Fetch(tp: PyObject**, val: PyObject**, tb: PyObject**)
extern def PyErr_Restore(tp: PyObject*, val: PyObject*, tb: PyObject*)
extern def PyErr_NormalizeException(tp: PyObject**, val: PyObject**, tb: PyObject**)
extern def PyErr_SetString(tp: PyObject*, msg: const str)
extern def PyErr_SetObject(tp: PyObject*, val: PyObject*)
extern def PyErr_BadArgument() -> rawptr
extern def PyErr_NoMemory() -> rawptr
extern def PyErr_Print()
extern def PyErr_ExceptionMatches(exc: PyObject*) -> int
extern def PyErr_GivenExceptionMatches(given: PyObject*, exc: PyObject*) -> int
# --- Built-in exception types ---
PyExc_BaseException: PyObject | t.CPtr | t.State
PyExc_Exception: PyObject | t.CPtr | t.State
PyExc_TypeError: PyObject | t.CPtr | t.State
PyExc_ValueError: PyObject | t.CPtr | t.State
PyExc_RuntimeError: PyObject | t.CPtr | t.State
PyExc_KeyError: PyObject | t.CPtr | t.State
PyExc_IndexError: PyObject | t.CPtr | t.State
PyExc_AttributeError: PyObject | t.CPtr | t.State
PyExc_ImportError: PyObject | t.CPtr | t.State
PyExc_OSError: PyObject | t.CPtr | t.State
PyExc_IOError: PyObject | t.CPtr | t.State
PyExc_ZeroDivisionError: PyObject | t.CPtr | t.State
PyExc_OverflowError: PyObject | t.CPtr | t.State
PyExc_MemoryError: PyObject | t.CPtr | t.State
PyExc_NameError: PyObject | t.CPtr | t.State
PyExc_StopIteration: PyObject | t.CPtr | t.State
PyExc_NotImplementedError: PyObject | t.CPtr | t.State
PyExc_SyntaxError: PyObject | t.CPtr | t.State
PyExc_FileNotFoundError: PyObject | t.CPtr | t.State
PyExc_PermissionError: PyObject | t.CPtr | t.State
PyExc_IsADirectoryError: PyObject | t.CPtr | t.State
PyExc_NotADirectoryError: PyObject | t.CPtr | t.State
extern PyExc_BaseException: PyObject*
extern PyExc_Exception: PyObject*
extern PyExc_TypeError: PyObject*
extern PyExc_ValueError: PyObject*
extern PyExc_RuntimeError: PyObject*
extern PyExc_KeyError: PyObject*
extern PyExc_IndexError: PyObject*
extern PyExc_AttributeError: PyObject*
extern PyExc_ImportError: PyObject*
extern PyExc_OSError: PyObject*
extern PyExc_IOError: PyObject*
extern PyExc_ZeroDivisionError: PyObject*
extern PyExc_OverflowError: PyObject*
extern PyExc_MemoryError: PyObject*
extern PyExc_NameError: PyObject*
extern PyExc_StopIteration: PyObject*
extern PyExc_NotImplementedError: PyObject*
extern PyExc_SyntaxError: PyObject*
extern PyExc_FileNotFoundError: PyObject*
extern PyExc_PermissionError: PyObject*
extern PyExc_IsADirectoryError: PyObject*
extern PyExc_NotADirectoryError: PyObject*
# --- Built-in functions ---
extern def Py_BuildValue(fmt: const str) -> PyObject*
extern def Py_VaBuildValue(fmt: const str, va: t.CPtr) -> PyObject*
extern def Py_VaBuildValue(fmt: const str, va: rawptr) -> PyObject*
# --- Type checks ---
@@ -355,21 +355,21 @@ extern def PyNone_Check(obj: PyObject*) -> int
# --- Memory management ---
extern def PyMem_Malloc(size: sizet) -> t.CPtr
extern def PyMem_Realloc(ptr: t.CPtr, size: sizet) -> t.CPtr
extern def PyMem_Free(ptr: t.CPtr)
extern def PyMem_Calloc(nelem: sizet, elsize: sizet) -> t.CPtr
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*, tp: t.CPtr) -> PyObject*
extern def PyObject_InitVar(obj: PyObject*, tp: t.CPtr, size: sizet) -> PyObject*
extern def PyMem_Malloc(size: sizet) -> rawptr
extern def PyMem_Realloc(ptr: rawptr, size: sizet) -> rawptr
extern def PyMem_Free(ptr: rawptr)
extern def PyMem_Calloc(nelem: sizet, elsize: sizet) -> rawptr
extern def PyObject_Malloc(size: sizet) -> rawptr
extern def PyObject_Realloc(ptr: rawptr, size: sizet) -> rawptr
extern def PyObject_Free(ptr: rawptr)
extern def PyObject_Calloc(nelem: sizet, elsize: sizet) -> rawptr
extern def PyObject_Init(obj: PyObject*, tp: rawptr) -> PyObject*
extern def PyObject_InitVar(obj: PyObject*, tp: rawptr, size: sizet) -> PyObject*
# --- File ops ---
extern def PyFile_FromString(filename: const str, mode: const str) -> PyObject*
extern def PyFile_AsFile(file: PyObject*) -> t.CPtr
extern def PyFile_AsFile(file: PyObject*) -> rawptr
extern def PyFile_WriteObject(obj: PyObject*, file: PyObject*, flags: int) -> int
extern def PyFile_WriteString(s: const str, file: PyObject*) -> int
@@ -377,33 +377,33 @@ extern def PyFile_WriteString(s: const str, file: PyObject*) -> int
# --- Compile/execute ---
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
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*
extern def PyEval_EvalFrame(frame: rawptr) -> PyObject*
extern def PyEval_CallObject(callable: PyObject*, args: PyObject*) -> PyObject*
extern def PyEval_CallFunction(callable: PyObject*, fmt: const str) -> PyObject*
extern def PyEval_CallMethod(obj: PyObject*, method: const str, fmt: const str) -> PyObject*
# --- PyRun ---
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_SimpleFile(fp: rawptr, filename: const str) -> int
extern def PyRun_AnyFile(fp: rawptr, filename: const str) -> int
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*
extern def PyRun_File(fp: rawptr, filename: const str, start: int, globs: PyObject*, locs: PyObject*) -> PyObject*
Py_single_input: int | t.State
Py_file_input: int | t.State
Py_eval_input: int | t.State
extern Py_single_input: int
extern Py_file_input: int
extern Py_eval_input: int
# --- Capsule ---
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_New(ptr: rawptr, name: const str, dtor: rawptr) -> PyObject*
extern def PyCapsule_GetPointer(cap: PyObject*, name: const str) -> rawptr
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_SetPointer(cap: PyObject*, ptr: rawptr) -> int
extern def PyCapsule_SetName(cap: PyObject*, name: const str) -> int
extern def PyCapsule_SetDestructor(cap: PyObject*, dtor: t.CPtr) -> int
extern def PyCapsule_SetDestructor(cap: PyObject*, dtor: rawptr) -> int
# --- Sequence ops ---
@@ -471,15 +471,15 @@ extern def PyWeakref_Check(obj: PyObject*) -> int
# --- Property descriptors ---
class PyGetSetDef:
name: const str
get: t.CPtr
set: t.CPtr
get: rawptr
set: rawptr
doc: const str
closure: t.CPtr
closure: rawptr
class PyMemberDef:
name: const str
type: int
offset: t.CPtrDiffT
offset: ptrdifft
flags: int
doc: const str
@@ -487,13 +487,13 @@ class PyMemberDef:
# --- sys module ---
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*): 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
extern def PySys_FormatStderr(fmt: const str): pass
extern def PySys_ResetWarnOptions()
extern def PySys_AddWarnOption(s: PyObject*)
extern def PySYS_AddXOption(s: PyObject*)
extern def PySys_WriteStdout(fmt: const str)
extern def PySys_WriteStderr(fmt: const str)
extern def PySys_FormatStdout(fmt: const str)
extern def PySys_FormatStderr(fmt: const str)
# --- Memory view ---
@@ -508,7 +508,7 @@ 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_Clear(s: PyObject*)
extern def PySet_Check(obj: PyObject*) -> int
extern def PyFrozenSet_New(iterable: PyObject*) -> PyObject*
extern def PyFrozenSet_Check(obj: PyObject*) -> int
@@ -517,8 +517,8 @@ extern def PyFrozenSet_Check(obj: PyObject*) -> int
# --- slice ---
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_Unpack(sl: PyObject*, start: ptrdifft*, stop: ptrdifft*, step: ptrdifft*)
extern def PySlice_AdjustIndices(length: sizet, start: ptrdifft*, stop: ptrdifft*, step: ptrdifft) -> sizet
extern def PySlice_Check(obj: PyObject*) -> int
@@ -528,36 +528,36 @@ extern def PySlice_Check(obj: PyObject*) -> int
class PyLongObj:
ptr: PyObject*
def __new__(self) -> 'PyLongObj' | t.CPtr:
return t.CPtr(malloc(PyLongObj.__sizeof__()))
def __new__(self) -> PyLongObj*:
return rawptr(malloc(PyLongObj.__sizeof__()))
@staticmethod
def from_long(val: t.CLong) -> 'PyLongObj' | t.CPtr:
def from_long(val: long) -> PyLongObj*:
obj: PyLongObj* = PyLongObj()
obj.ptr = PyLong_FromLong(val)
return obj
def __add__(self, other: PyLongObj*) -> 'PyLongObj' | t.CPtr:
def __add__(self, other: PyLongObj*) -> PyLongObj*:
res: PyLongObj* = PyLongObj()
res.ptr = PyNumber_Add(self.ptr, other.ptr)
return res
def __sub__(self, other: PyLongObj*) -> 'PyLongObj' | t.CPtr:
def __sub__(self, other: PyLongObj*) -> PyLongObj*:
res: PyLongObj* = PyLongObj()
res.ptr = PyNumber_Subtract(self.ptr, other.ptr)
return res
def __mul__(self, other: PyLongObj*) -> 'PyLongObj' | t.CPtr:
def __mul__(self, other: PyLongObj*) -> PyLongObj*:
res: PyLongObj* = PyLongObj()
res.ptr = PyNumber_Multiply(self.ptr, other.ptr)
return res
def __neg__(self) -> 'PyLongObj' | t.CPtr:
def __neg__(self) -> PyLongObj*:
res: PyLongObj* = PyLongObj()
res.ptr = PyNumber_Negative(self.ptr)
return res
def to_long(self) -> t.CLong:
def to_long(self) -> long:
return PyLong_AsLong(self.ptr)
def __str__(self) -> PyObject*:
@@ -571,36 +571,36 @@ class PyLongObj:
class PyFloatObj:
ptr: PyObject*
def __new__(self) -> 'PyFloatObj' | t.CPtr:
return t.CPtr(malloc(PyFloatObj.__sizeof__()))
def __new__(self) -> PyFloatObj*:
return rawptr(malloc(PyFloatObj.__sizeof__()))
@staticmethod
def from_double(val: double) -> 'PyFloatObj' | t.CPtr:
def from_double(val: double) -> PyFloatObj*:
obj: PyFloatObj* = PyFloatObj()
obj.ptr = PyFloat_FromDouble(val)
return obj
def __add__(self, other: PyFloatObj*) -> 'PyFloatObj' | t.CPtr:
def __add__(self, other: PyFloatObj*) -> PyFloatObj*:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_Add(self.ptr, other.ptr)
return res
def __sub__(self, other: PyFloatObj*) -> 'PyFloatObj' | t.CPtr:
def __sub__(self, other: PyFloatObj*) -> PyFloatObj*:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_Subtract(self.ptr, other.ptr)
return res
def __mul__(self, other: PyFloatObj*) -> 'PyFloatObj' | t.CPtr:
def __mul__(self, other: PyFloatObj*) -> PyFloatObj*:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_Multiply(self.ptr, other.ptr)
return res
def __truediv__(self, other: PyFloatObj*) -> 'PyFloatObj' | t.CPtr:
def __truediv__(self, other: PyFloatObj*) -> PyFloatObj*:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_TrueDivide(self.ptr, other.ptr)
return res
def __neg__(self) -> 'PyFloatObj' | t.CPtr:
def __neg__(self) -> PyFloatObj*:
res: PyFloatObj* = PyFloatObj()
res.ptr = PyNumber_Negative(self.ptr)
return res
@@ -619,21 +619,21 @@ class PyFloatObj:
class PyUnicodeObj:
ptr: PyObject*
def __new__(self) -> 'PyUnicodeObj' | t.CPtr:
return t.CPtr(malloc(PyUnicodeObj.__sizeof__()))
def __new__(self) -> PyUnicodeObj*:
return rawptr(malloc(PyUnicodeObj.__sizeof__()))
@staticmethod
def from_string(s: char*) -> 'PyUnicodeObj' | t.CPtr:
def from_string(s: char*) -> PyUnicodeObj*:
obj: PyUnicodeObj* = PyUnicodeObj()
obj.ptr = PyUnicode_FromString(s)
return obj
def __add__(self, other: PyUnicodeObj*) -> 'PyUnicodeObj' | t.CPtr:
def __add__(self, other: PyUnicodeObj*) -> PyUnicodeObj*:
res: PyUnicodeObj* = PyUnicodeObj()
res.ptr = PyUnicode_Concat(self.ptr, other.ptr)
return res
def __len__(self) -> t.CPtrDiffT:
def __len__(self) -> ptrdifft:
return PyUnicode_GetLength(self.ptr)
def as_utf8(self) -> char*:
@@ -650,11 +650,11 @@ class PyUnicodeObj:
class PyListObj:
ptr: PyObject*
def __new__(self) -> 'PyListObj' | t.CPtr:
return t.CPtr(malloc(PyListObj.__sizeof__()))
def __new__(self) -> 'PyListObj' | rawptr:
return rawptr(malloc(PyListObj.__sizeof__()))
@staticmethod
def new() -> 'PyListObj' | t.CPtr:
def new() -> 'PyListObj' | rawptr:
obj: PyListObj* = PyListObj()
obj.ptr = PyList_New(0)
return obj
@@ -679,11 +679,11 @@ class PyListObj:
class PyDictObj:
ptr: PyObject*
def __new__(self) -> 'PyDictObj' | t.CPtr:
return t.CPtr(malloc(PyDictObj.__sizeof__()))
def __new__(self) -> PyDictObj*:
return rawptr(malloc(PyDictObj.__sizeof__()))
@staticmethod
def new() -> 'PyDictObj' | t.CPtr:
def new() -> PyDictObj*:
obj: PyDictObj* = PyDictObj()
obj.ptr = PyDict_New()
return obj
+72 -74
View File
@@ -1,5 +1,3 @@
import t, c
from t import CInt, CLong, CDouble, CPtr, CSizeT
from stdio import printf
import cpython
import testcheck
@@ -18,31 +16,31 @@ def test_long_operations():
cpython.Py_Initialize()
# Create int
py_num: cpython.PyObject | CPtr = cpython.PyLong_FromLong(12345)
py_num: cpython.PyObject* = cpython.PyLong_FromLong(12345)
testcheck.check(py_num != 0, "PyLong_FromLong != NULL", "PyLong_FromLong != NULL")
# Int to string
py_str: cpython.PyObject | CPtr = cpython.PyObject_Str(py_num)
py_str: cpython.PyObject* = cpython.PyObject_Str(py_num)
testcheck.check(py_str != 0, "PyObject_Str != NULL", "PyObject_Str != NULL")
# Get C string
c_str: char | CPtr = cpython.PyUnicode_AsUTF8(py_str)
c_str: str = cpython.PyUnicode_AsUTF8(py_str)
testcheck.check(c_str != 0, "PyUnicode_AsUTF8 != NULL", "PyUnicode_AsUTF8 != NULL")
printf(" PyLong_FromLong(12345) -> str = %s\n", c_str)
# Read back
val: CLong = cpython.PyLong_AsLong(py_num)
val: long = cpython.PyLong_AsLong(py_num)
testcheck.check(val == 12345, "PyLong_AsLong == 12345", "PyLong_AsLong == 12345")
# Negative
py_neg: cpython.PyObject | CPtr = cpython.PyLong_FromLong(-999)
neg_val: CLong = cpython.PyLong_AsLong(py_neg)
py_neg: cpython.PyObject* = cpython.PyLong_FromLong(-999)
neg_val: long = cpython.PyLong_AsLong(py_neg)
testcheck.check(neg_val == -999, "PyLong_FromLong(-999) == -999", "PyLong_FromLong(-999) == -999")
# Float to int
py_dbl: cpython.PyObject | CPtr = cpython.PyFloat_FromDouble(3.14159)
py_dbl: cpython.PyObject* = cpython.PyFloat_FromDouble(3.14159)
testcheck.check(py_dbl != 0, "PyFloat_FromDouble != NULL", "PyFloat_FromDouble != NULL")
dbl_val: CDouble = cpython.PyFloat_AsDouble(py_dbl)
dbl_val: double = cpython.PyFloat_AsDouble(py_dbl)
testcheck.check(dbl_val > 3.14 and dbl_val < 3.15, "PyFloat_AsDouble ~= 3.14", "PyFloat_AsDouble ~= 3.14")
# Cleanup
@@ -59,24 +57,24 @@ def test_string_operations():
cpython.Py_Initialize()
# Create from C string
py_s1: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("Hello, Viper!")
py_s1: cpython.PyObject* = cpython.PyUnicode_FromString("Hello, Viper!")
testcheck.check(py_s1 != 0, "PyUnicode_FromString != NULL", "PyUnicode_FromString != NULL")
# Get UTF-8
utf8: char | CPtr = cpython.PyUnicode_AsUTF8(py_s1)
utf8: str = cpython.PyUnicode_AsUTF8(py_s1)
testcheck.check(utf8 != 0, "AsUTF8 != NULL", "AsUTF8 != NULL")
printf(" PyUnicode_FromString -> %s\n", utf8)
# String length
# PyUnicode_GetLength 返回 CPython 的 Py_ssize_t(= ptrdiff_t,64 位);CLong 在本目标
# (x86_64-pc-windows-gnu / LLP64) 只有 32 位,用 CLong 接收会触发「隐式窄化禁止」。
length: t.CPtrDiffT = cpython.PyUnicode_GetLength(py_s1)
length: ptrdifft = cpython.PyUnicode_GetLength(py_s1)
testcheck.check(length == 13, "GetLength == 13", "GetLength == 13")
# String concat
py_s2: cpython.PyObject | CPtr = cpython.PyUnicode_FromString(" World")
py_concat: cpython.PyObject | CPtr = cpython.PyUnicode_Concat(py_s1, py_s2)
concat_utf8: char | CPtr = cpython.PyUnicode_AsUTF8(py_concat)
py_s2: cpython.PyObject* = cpython.PyUnicode_FromString(" World")
py_concat: cpython.PyObject* = cpython.PyUnicode_Concat(py_s1, py_s2)
concat_utf8: str = cpython.PyUnicode_AsUTF8(py_concat)
testcheck.check(py_concat != 0, "Concat != NULL", "Concat != NULL")
printf(" Concat -> %s\n", concat_utf8)
@@ -93,28 +91,28 @@ def test_list_operations():
cpython.Py_Initialize()
# Create list
py_list: cpython.PyObject | CPtr = cpython.PyList_New(0)
py_list: cpython.PyObject* = cpython.PyList_New(0)
testcheck.check(py_list != 0, "PyList_New != NULL", "PyList_New != NULL")
# Append elements
py_i1: cpython.PyObject | CPtr = cpython.PyLong_FromLong(10)
py_i2: cpython.PyObject | CPtr = cpython.PyLong_FromLong(20)
py_i3: cpython.PyObject | CPtr = cpython.PyLong_FromLong(30)
py_i1: cpython.PyObject* = cpython.PyLong_FromLong(10)
py_i2: cpython.PyObject* = cpython.PyLong_FromLong(20)
py_i3: cpython.PyObject* = cpython.PyLong_FromLong(30)
cpython.PyList_Append(py_list, py_i1)
cpython.PyList_Append(py_list, py_i2)
cpython.PyList_Append(py_list, py_i3)
# Check size
list_size: CSizeT = cpython.PyList_Size(py_list)
list_size: sizet = cpython.PyList_Size(py_list)
testcheck.check(list_size == 3, "PyList_Size == 3", "PyList_Size == 3")
# Get elements
item0: cpython.PyObject | CPtr = cpython.PyList_GetItem(py_list, 0)
val0: CLong = cpython.PyLong_AsLong(item0)
item0: cpython.PyObject* = cpython.PyList_GetItem(py_list, 0)
val0: long = cpython.PyLong_AsLong(item0)
testcheck.check(val0 == 10, "list[0] == 10", "list[0] == 10")
item2: cpython.PyObject | CPtr = cpython.PyList_GetItem(py_list, 2)
val2: CLong = cpython.PyLong_AsLong(item2)
item2: cpython.PyObject* = cpython.PyList_GetItem(py_list, 2)
val2: long = cpython.PyLong_AsLong(item2)
testcheck.check(val2 == 30, "list[2] == 30", "list[2] == 30")
# Cleanup
@@ -131,33 +129,33 @@ def test_dict_operations():
cpython.Py_Initialize()
# Create dict
py_dict: cpython.PyObject | CPtr = cpython.PyDict_New()
py_dict: cpython.PyObject* = cpython.PyDict_New()
testcheck.check(py_dict != 0, "PyDict_New != NULL", "PyDict_New != NULL")
# Set key/value pairs
py_key1: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("name")
py_val1: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("Viper")
py_key1: cpython.PyObject* = cpython.PyUnicode_FromString("name")
py_val1: cpython.PyObject* = cpython.PyUnicode_FromString("Viper")
cpython.PyDict_SetItem(py_dict, py_key1, py_val1)
py_key2: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("version")
py_val2: cpython.PyObject | CPtr = cpython.PyLong_FromLong(1)
py_key2: cpython.PyObject* = cpython.PyUnicode_FromString("version")
py_val2: cpython.PyObject* = cpython.PyLong_FromLong(1)
cpython.PyDict_SetItem(py_dict, py_key2, py_val2)
# Check size
dict_size: CSizeT = cpython.PyDict_Size(py_dict)
dict_size: sizet = cpython.PyDict_Size(py_dict)
testcheck.check(dict_size == 2, "PyDict_Size == 2", "PyDict_Size == 2")
# Get value
got_val: cpython.PyObject | CPtr = cpython.PyDict_GetItem(py_dict, py_key1)
got_val: cpython.PyObject* = cpython.PyDict_GetItem(py_dict, py_key1)
testcheck.check(got_val != 0, "GetItem(name) != NULL", "GetItem(name) != NULL")
got_str: char | CPtr = cpython.PyUnicode_AsUTF8(got_val)
got_str: str = cpython.PyUnicode_AsUTF8(got_val)
testcheck.check(got_str != 0, "name == Viper", "name == Viper")
printf(" dict['name'] = %s\n", got_str)
# Use GetItemString
got_ver: cpython.PyObject | CPtr = cpython.PyDict_GetItemString(py_dict, "version")
got_ver: cpython.PyObject* = cpython.PyDict_GetItemString(py_dict, "version")
testcheck.check(got_ver != 0, "GetItemString(version) != NULL", "GetItemString(version) != NULL")
ver_val: CLong = cpython.PyLong_AsLong(got_ver)
ver_val: long = cpython.PyLong_AsLong(got_ver)
testcheck.check(ver_val == 1, "version == 1", "version == 1")
# Cleanup
@@ -175,15 +173,15 @@ def test_pyrun_string():
cpython.Py_Initialize()
# Run simple Python code
rc: CInt = cpython.PyRun_SimpleString("print('Hello from embedded Python!')")
rc: int = cpython.PyRun_SimpleString("print('Hello from embedded Python!')")
testcheck.check(rc == 0, "PyRun_SimpleString == 0", "PyRun_SimpleString == 0")
# Run assignment
rc2: CInt = cpython.PyRun_SimpleString("x = 6 * 7")
rc2: int = cpython.PyRun_SimpleString("x = 6 * 7")
testcheck.check(rc2 == 0, "PyRun_SimpleString(assign) == 0", "PyRun_SimpleString(assign) == 0")
# Read result
rc3: CInt = cpython.PyRun_SimpleString("print(f'The answer is {x}')")
rc3: int = cpython.PyRun_SimpleString("print(f'The answer is {x}')")
testcheck.check(rc3 == 0, "PyRun_SimpleString(print) == 0", "PyRun_SimpleString(print) == 0")
cpython.Py_Finalize()
@@ -194,21 +192,21 @@ def test_import_module():
cpython.Py_Initialize()
# Import math module
math_mod: cpython.PyObject | CPtr = cpython.PyImport_ImportModule("math")
math_mod: cpython.PyObject* = cpython.PyImport_ImportModule("math")
testcheck.check(math_mod != 0, "import math != NULL", "import math != NULL")
if math_mod != 0:
# Get math.pi
pi_val: cpython.PyObject | CPtr = cpython.PyObject_GetAttrString(math_mod, "pi")
pi_val: cpython.PyObject* = cpython.PyObject_GetAttrString(math_mod, "pi")
testcheck.check(pi_val != 0, "math.pi != NULL", "math.pi != NULL")
if pi_val != 0:
pi_dbl: CDouble = cpython.PyFloat_AsDouble(pi_val)
pi_dbl: double = cpython.PyFloat_AsDouble(pi_val)
testcheck.check(pi_dbl > 3.14 and pi_dbl < 3.15, "math.pi ~= 3.14", "math.pi ~= 3.14")
printf(" math.pi = %f\n", pi_dbl)
cpython.Py_DecRef(pi_val)
# Get math.sqrt function
sqrt_func: cpython.PyObject | CPtr = cpython.PyObject_GetAttrString(math_mod, "sqrt")
sqrt_func: cpython.PyObject* = cpython.PyObject_GetAttrString(math_mod, "sqrt")
testcheck.check(sqrt_func != 0, "math.sqrt != NULL", "math.sqrt != NULL")
if sqrt_func != 0:
cpython.Py_DecRef(sqrt_func)
@@ -223,20 +221,20 @@ def test_operator_overload():
cpython.Py_Initialize()
# --- PyLongObj: from_long, to_long, +, -, *, - (neg) ---
a: cpython.PyLongObj | CPtr = cpython.PyLongObj.from_long(10)
b: cpython.PyLongObj | CPtr = cpython.PyLongObj.from_long(3)
a: cpython.PyLongObj* = cpython.PyLongObj.from_long(10)
b: cpython.PyLongObj* = cpython.PyLongObj.from_long(3)
testcheck.check(a != 0 and b != 0, "PyLongObj.from_long != NULL", "PyLongObj.from_long != NULL")
add_r: cpython.PyLongObj | CPtr = a + b
add_r: cpython.PyLongObj* = a + b
testcheck.check(add_r.to_long() == 13, "PyLongObj 10 + 3 == 13", "PyLongObj 10 + 3 == 13")
sub_r: cpython.PyLongObj | CPtr = a - b
sub_r: cpython.PyLongObj* = a - b
testcheck.check(sub_r.to_long() == 7, "PyLongObj 10 - 3 == 7", "PyLongObj 10 - 3 == 7")
mul_r: cpython.PyLongObj | CPtr = a * b
mul_r: cpython.PyLongObj* = a * b
testcheck.check(mul_r.to_long() == 30, "PyLongObj 10 * 3 == 30", "PyLongObj 10 * 3 == 30")
neg_r: cpython.PyLongObj | CPtr = -b
neg_r: cpython.PyLongObj* = -b
testcheck.check(neg_r.to_long() == -3, "PyLongObj -3 == -3", "PyLongObj -3 == -3")
mul_r.dec_ref()
@@ -247,23 +245,23 @@ def test_operator_overload():
a.dec_ref()
# --- PyFloatObj: from_double, to_double, +, -, *, /, - (neg) ---
fa: cpython.PyFloatObj | CPtr = cpython.PyFloatObj.from_double(10.0)
fb: cpython.PyFloatObj | CPtr = cpython.PyFloatObj.from_double(4.0)
fa: cpython.PyFloatObj* = cpython.PyFloatObj.from_double(10.0)
fb: cpython.PyFloatObj* = cpython.PyFloatObj.from_double(4.0)
testcheck.check(fa != 0 and fb != 0, "PyFloatObj.from_double != NULL", "PyFloatObj.from_double != NULL")
fadd: cpython.PyFloatObj | CPtr = fa + fb
fadd: cpython.PyFloatObj* = fa + fb
testcheck.check(fadd.to_double() == 14.0, "PyFloatObj 10.0 + 4.0 == 14.0", "PyFloatObj 10.0 + 4.0 == 14.0")
fsub: cpython.PyFloatObj | CPtr = fa - fb
fsub: cpython.PyFloatObj* = fa - fb
testcheck.check(fsub.to_double() == 6.0, "PyFloatObj 10.0 - 4.0 == 6.0", "PyFloatObj 10.0 - 4.0 == 6.0")
fmul: cpython.PyFloatObj | CPtr = fa * fb
fmul: cpython.PyFloatObj* = fa * fb
testcheck.check(fmul.to_double() == 40.0, "PyFloatObj 10.0 * 4.0 == 40.0", "PyFloatObj 10.0 * 4.0 == 40.0")
fdiv: cpython.PyFloatObj | CPtr = fa / fb
fdiv: cpython.PyFloatObj* = fa / fb
testcheck.check(fdiv.to_double() == 2.5, "PyFloatObj 10.0 / 4.0 == 2.5", "PyFloatObj 10.0 / 4.0 == 2.5")
fneg: cpython.PyFloatObj | CPtr = -fb
fneg: cpython.PyFloatObj* = -fb
testcheck.check(fneg.to_double() == -4.0, "PyFloatObj -4.0 == -4.0", "PyFloatObj -4.0 == -4.0")
fadd.dec_ref()
@@ -275,17 +273,17 @@ def test_operator_overload():
fa.dec_ref()
# --- PyUnicodeObj: from_string, as_utf8, len, + (concat) ---
sa: cpython.PyUnicodeObj | CPtr = cpython.PyUnicodeObj.from_string("Hello")
sb: cpython.PyUnicodeObj | CPtr = cpython.PyUnicodeObj.from_string(" World")
sa: cpython.PyUnicodeObj* = cpython.PyUnicodeObj.from_string("Hello")
sb: cpython.PyUnicodeObj* = cpython.PyUnicodeObj.from_string(" World")
testcheck.check(sa != 0 and sb != 0, "PyUnicodeObj.from_string != NULL", "PyUnicodeObj.from_string != NULL")
sc: cpython.PyUnicodeObj | CPtr = sa + sb
sc_utf8: char | CPtr = sc.as_utf8()
sc: cpython.PyUnicodeObj* = sa + sb
sc_utf8: str = sc.as_utf8()
testcheck.check(sc_utf8 != 0, "PyUnicodeObj concat != NULL", "PyUnicodeObj concat != NULL")
if sc_utf8 != 0:
printf(" PyUnicodeObj 'Hello' + ' World' = %s\n", sc_utf8)
sa_len: t.CPtrDiffT = len(sa)
sa_len: ptrdifft = len(sa)
testcheck.check(sa_len == 5, "PyUnicodeObj len('Hello') == 5", "PyUnicodeObj len('Hello') == 5")
sc.dec_ref()
@@ -293,24 +291,24 @@ def test_operator_overload():
sa.dec_ref()
# --- PyListObj: new, append, len, [], []= ---
lst: cpython.PyListObj | CPtr = cpython.PyListObj.new()
lst: cpython.PyListObj* = cpython.PyListObj.new()
testcheck.check(lst != 0, "PyListObj.new != NULL", "PyListObj.new != NULL")
if lst != 0:
e1: cpython.PyObject | CPtr = cpython.PyLong_FromLong(100)
e2: cpython.PyObject | CPtr = cpython.PyLong_FromLong(200)
e3: cpython.PyObject | CPtr = cpython.PyLong_FromLong(300)
e1: cpython.PyObject* = cpython.PyLong_FromLong(100)
e2: cpython.PyObject* = cpython.PyLong_FromLong(200)
e3: cpython.PyObject* = cpython.PyLong_FromLong(300)
lst.append(e1)
lst.append(e2)
lst.append(e3)
testcheck.check(len(lst) == 3, "PyListObj len == 3", "PyListObj len == 3")
item0: cpython.PyObject | CPtr = lst[sizet(0)]
item0: cpython.PyObject* = lst[sizet(0)]
testcheck.check(cpython.PyLong_AsLong(item0) == 100, "PyListObj lst[0] == 100", "PyListObj lst[0] == 100")
# __setitem__
e4: cpython.PyObject | CPtr = cpython.PyLong_FromLong(999)
e4: cpython.PyObject* = cpython.PyLong_FromLong(999)
lst[sizet(1)] = e4
item1: cpython.PyObject | CPtr = lst[sizet(1)]
item1: cpython.PyObject* = lst[sizet(1)]
testcheck.check(cpython.PyLong_AsLong(item1) == 999, "PyListObj lst[1] = 999", "PyListObj lst[1] = 999")
cpython.Py_DecRef(e4)
@@ -320,23 +318,23 @@ def test_operator_overload():
lst.dec_ref()
# --- PyDictObj: new, [], []=, len, set_string, get_string ---
dct: cpython.PyDictObj | CPtr = cpython.PyDictObj.new()
dct: cpython.PyDictObj* = cpython.PyDictObj.new()
testcheck.check(dct != 0, "PyDictObj.new != NULL", "PyDictObj.new != NULL")
if dct != 0:
dk1: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("lang")
dv1: cpython.PyObject | CPtr = cpython.PyUnicode_FromString("Viper")
dk1: cpython.PyObject* = cpython.PyUnicode_FromString("lang")
dv1: cpython.PyObject* = cpython.PyUnicode_FromString("Viper")
dct[dk1] = dv1
testcheck.check(len(dct) == 1, "PyDictObj len == 1", "PyDictObj len == 1")
got_lang: cpython.PyObject | CPtr = dct[dk1]
got_str: char | CPtr = cpython.PyUnicode_AsUTF8(got_lang)
got_lang: cpython.PyObject* = dct[dk1]
got_str: str = cpython.PyUnicode_AsUTF8(got_lang)
testcheck.check(got_str != 0, "PyDictObj dct['lang'] == Viper", "PyDictObj dct['lang'] == Viper")
if got_str != 0:
printf(" PyDictObj dct['lang'] = %s\n", got_str)
# get_string / set_string
dct.set_string("ver", cpython.PyLong_FromLong(3))
got_ver: cpython.PyObject | CPtr = dct.get_string("ver")
got_ver: cpython.PyObject* = dct.get_string("ver")
testcheck.check(got_ver != 0 and cpython.PyLong_AsLong(got_ver) == 3, "PyDictObj get_string('ver') == 3", "PyDictObj get_string('ver') == 3")
cpython.Py_DecRef(dv1)
@@ -346,7 +344,7 @@ def test_operator_overload():
cpython.Py_Finalize()
def main() -> CInt | t.CExport:
export def main() -> int:
testcheck.begin("CPython Integration Test")
test_init_finalize()
+5 -6
View File
@@ -1,4 +1,3 @@
import t, c
from stdint import *
import stdio
@@ -7,22 +6,22 @@ def bump(v: char) -> char:
return char(v + 1)
def main() -> int | t.CExport:
export def main() -> int:
# 1) char annotation: char = t.CChar = i8 (scalar builtin, not a pointer)
ch: char = 65
stdio.printf("1 char annot: %d (expect 65)\n", int(ch))
stdio.printf("1 char annot: %d (expect 65)\n", ch)
# 2) char() cast int to char: 300 truncates to i8, giving 44
big: char = char(300)
stdio.printf("2 char cast trunc: %d (expect 44)\n", int(big))
stdio.printf("2 char cast trunc: %d (expect 44)\n", big)
# 3) Function returns char (stored as i8)
nx: char = bump(ch)
stdio.printf("3 char return: %d (expect 66)\n", int(nx))
stdio.printf("3 char return: %d (expect 66)\n", nx)
# 4) Single-char literal 'Z' assigned to char (90)
lit: char = 'Z'
stdio.printf("4 char literal: %d (expect 90)\n", int(lit))
stdio.printf("4 char literal: %d (expect 90)\n", lit)
# 5) char in arithmetic (i8 promoted when mixed with int)
s: int = ch + 1
+24 -45
View File
@@ -1,21 +1,19 @@
import stdio
import stdlib
import stdint
import t, c
class SimpleData():
struct SimpleData:
x: int
y: int
class Point3D():
struct Point3D:
x: float
y: float
z: float
class Student():
class Student:
name: char*
age: int
score: int
@@ -32,7 +30,7 @@ class Student():
return self.score
class Counter():
class Counter:
value: int
def __init__(self, initial: int):
@@ -45,9 +43,9 @@ class Counter():
return self.value
class StackObj():
struct StackObj:
data: int
next_ptr: t.CPtr
next_ptr: rawptr
def TestBasicDataClass():
@@ -100,7 +98,7 @@ def TestStackAllocation():
def TestHeapAllocation():
stdio.printf("=== Test Heap Allocation ===\n")
ptr: t.CPtr = stdlib.malloc(1024)
ptr: rawptr = stdlib.malloc(1024)
if ptr != 0:
stdio.printf("Allocated 1024 bytes at %p\n", ptr)
stdlib.free(ptr)
@@ -112,7 +110,7 @@ def TestHeapAllocation():
def TestHeapObjectWithInit():
stdio.printf("=== Test Heap Object with Init ===\n")
mem_size: sizet = 256
ptr: t.CPtr = stdlib.malloc(mem_size)
ptr: rawptr = stdlib.malloc(mem_size)
if ptr != 0:
stdio.printf("Allocated %d bytes\n", mem_size)
stdlib.free(ptr)
@@ -156,70 +154,51 @@ def TestClassWithBitFields():
def TestIntArray():
stdio.printf("=== Test Int Array ===\n")
arr: t.CArray[int, 5] = t.CArray[int, 5]()
for i in range(5):
arr: [5]int = None
for i in range(5):
arr[i] = i * 10
for i in range(5):
for i in range(5):
stdio.printf("arr[%d]=%d\n", i, arr[i])
def TestFloatArray():
stdio.printf("=== Test Float Array ===\n")
farr: t.CArray[float, 4] = t.CArray[float, 4]()
farr[0] = 1.5
farr[1] = 2.5
farr[2] = 3.5
farr[3] = 4.5
for i in range(4):
farr: [4]float = [1.5, 2.5, 3.5, 4.5]
for i in range(4):
stdio.printf("farr[%d]=%.1f\n", i, farr[i])
def TestCharArray():
stdio.printf("=== Test Char Array (String) ===\n")
str_arr: t.CArray[char, 32] = t.CArray[char, 32]()
str_arr[0] = 'H'
str_arr[1] = 'e'
str_arr[2] = 'l'
str_arr[3] = 'l'
str_arr[4] = 'o'
str_arr[5] = '\0'
str_arr: [32]char = ['H', 'e', 'l', 'l', 'o', '\0']
stdio.printf("String: %s\n", str_arr)
def TestNestedArray():
stdio.printf("=== Test Nested Array (Array of Arrays) ===\n")
row0: t.CArray[int, 3] = t.CArray[int, 3]()
row1: t.CArray[int, 3] = t.CArray[int, 3]()
row0[0] = 0
row0[1] = 1
row0[2] = 2
row1[0] = 10
row1[1] = 11
row1[2] = 12
for i in range(3):
row0: [3]int = [0, 1, 2]
row1: [3]int = [10, 11, 12]
for i in range(3):
stdio.printf("row0[%d]=%d ", i, row0[i])
stdio.printf("\n")
for i in range(3):
for i in range(3):
stdio.printf("row1[%d]=%d ", i, row1[i])
stdio.printf("\n")
def TestArrayWithStruct():
stdio.printf("=== Test Array with Struct ===\n")
points: t.CArray[SimpleData, 3] = t.CArray[SimpleData, 3]()
for i in range(3):
points: [3]SimpleData = None
for i in range(3):
points[i].x = i * 10
points[i].y = i * 100
for i in range(3):
for i in range(3):
stdio.printf("Point[%d]: x=%d, y=%d\n", i, points[i].x, points[i].y)
def TestArrayPointer():
stdio.printf("=== Test Array Pointer ===\n")
data: t.CArray[int, 8] = t.CArray[int, 8]()
data[0] = 100
data[1] = 200
data[2] = 300
data: [8]int = [100, 200, 300]
ptr: int* = data
stdio.printf("ptr[0]=%d\n", ptr[0])
stdio.printf("ptr[1]=%d\n", ptr[1])
@@ -228,5 +207,5 @@ def TestArrayPointer():
def TestDynamicString():
stdio.printf("=== Test Dynamic String ===\n")
name: str = "TransPyC"
stdio.printf("Hello %s!\n", name)
name: str = "ViperC"
stdio.printf("Hello %s!\n", name)
+1 -2
View File
@@ -1,9 +1,8 @@
import t, c
import testcheck
import class_test
def main() -> int:
export def main() -> int:
testcheck.begin("ClassArrayTest: 类与数组测试")
testcheck.section("CLASS TESTS")
+6 -12
View File
@@ -1,34 +1,28 @@
import t
import stdio
import testcheck
# ClosureCallTest - minimal repro: call through a t.CPtr function pointer
# f is t.CPtr (i8*); the compiler must treat its pointee as callable.
# nonlocal test: a nested function mutates an outer local
def make_counter() -> t.CPtr:
def make_counter() -> callable[[], int]:
count: int = 0
# Inner closure captures count
def counter() -> int:
nonlocal count
count = count + 1
return count
return counter
def test_closure_call():
"""Verify calling a t.CPtr function pointer."""
testcheck.section("Closure call via t.CPtr")
f: t.CPtr = make_counter()
"""Verify calling a rawptr function pointer."""
testcheck.section("Closure call via rawptr")
f: callable[[], int] = make_counter()
v: int = f()
testcheck.check(v == 1, "f() first call = 1", "expect 1")
# testcheck.check(v2 == 2, "f2() first call = 2", "expect 2")
def main() -> int:
testcheck.begin("ClosureCallTest: t.CPtr function pointer call")
testcheck.begin("ClosureCallTest: rawptr function pointer call")
test_closure_call()
return testcheck.end()
+1 -2
View File
@@ -1,4 +1,3 @@
import t
import stdio
import testcheck
@@ -112,7 +111,7 @@ def test_nonlocal_loop():
# ============================================================
# Test 8: global array operation
# ============================================================
g_arr: t.CArray[int, 4] = [0]
g_arr: [4]int = None
def test_global_array():
testcheck.section("Test 8: global array")
+2 -3
View File
@@ -1,4 +1,3 @@
import t
import stdio
import testcheck
@@ -64,7 +63,7 @@ def test_global_cross_functions():
# ============================================================
def test_nested_ref_capture():
testcheck.section("Test 4: nested function ref capture")
arr: t.CArray[int, 4] = [0]
arr: [4]int = None
def fill():
nonlocal arr
for i in range(4):
@@ -186,7 +185,7 @@ def test_nonlocal_while():
# ============================================================
# Test 12: nested function modifies struct fields
# ============================================================
class Point:
struct Point:
x: int
y: int
-1
View File
@@ -1,4 +1,3 @@
import t, c
from stdint import *
import stdio
import coro
+33 -46
View File
@@ -1,4 +1,3 @@
import t
from stdio import printf
import testcheck
@@ -6,10 +5,10 @@ import testcheck
# ctx: per-call frame-local context (32 bytes); args_ptr/ret_ptr are read-write; pre-phase returns 0=skip, 1=call once, N=loop N.
# @log: print enter/exit, return 1 (call once)
def log(ctx: t.CPtr, func_name: str, phase: int,
args_ptr: t.CPtr,
ret_ptr: t.CPtr,
decor_args_ptr: t.CPtr) -> int | t.CExport:
export def log(ctx: rawptr, func_name: str, phase: int,
args_ptr: rawptr,
ret_ptr: rawptr,
decor_args_ptr: rawptr) -> int:
if phase == 0:
printf("[LOG] >> %s enter\n", func_name)
return 1
@@ -18,10 +17,10 @@ def log(ctx: t.CPtr, func_name: str, phase: int,
return 0
# @trace: verbose tracing
def trace(ctx: t.CPtr, func_name: str, phase: int,
args_ptr: t.CPtr,
ret_ptr: t.CPtr,
decor_args_ptr: t.CPtr) -> int | t.CExport:
export def trace(ctx: rawptr, func_name: str, phase: int,
args_ptr: rawptr,
ret_ptr: rawptr,
decor_args_ptr: rawptr) -> int:
if phase == 0:
printf("[TRACE] calling %s...\n", func_name)
return 1
@@ -33,10 +32,10 @@ def trace(ctx: t.CPtr, func_name: str, phase: int,
# A global is used because i8* to i32* pointer casts are not supported yet.
_timing_tmp: int = 0
def timing(ctx: t.CPtr, func_name: str, phase: int,
args_ptr: t.CPtr,
ret_ptr: t.CPtr,
decor_args_ptr: t.CPtr) -> int | t.CExport:
export def timing(ctx: rawptr, func_name: str, phase: int,
args_ptr: rawptr,
ret_ptr: rawptr,
decor_args_ptr: rawptr) -> int:
global _timing_tmp
if phase == 0:
_timing_tmp = 100
@@ -48,10 +47,10 @@ def timing(ctx: t.CPtr, func_name: str, phase: int,
return 0
# @repeat (with args, flow hijack): call the original function N times
def repeat(ctx: t.CPtr, func_name: str, phase: int,
args_ptr: t.CPtr,
ret_ptr: t.CPtr,
decor_args_ptr: t.CPtr) -> int | t.CExport:
export def repeat(ctx: rawptr, func_name: str, phase: int,
args_ptr: rawptr,
ret_ptr: rawptr,
decor_args_ptr: rawptr) -> int:
if phase == 0:
printf("[REPEAT] %s will run 3 times\n", func_name)
return 3
@@ -62,10 +61,10 @@ def repeat(ctx: t.CPtr, func_name: str, phase: int,
# @skip: skip the original call (flow hijack, returns 0)
_skip_count: int = 0
def skip(ctx: t.CPtr, func_name: str, phase: int,
args_ptr: t.CPtr,
ret_ptr: t.CPtr,
decor_args_ptr: t.CPtr) -> int | t.CExport:
export def skip(ctx: rawptr, func_name: str, phase: int,
args_ptr: rawptr,
ret_ptr: rawptr,
decor_args_ptr: rawptr) -> int:
global _skip_count
if phase == 0:
_skip_count = _skip_count + 1
@@ -78,10 +77,10 @@ def skip(ctx: t.CPtr, func_name: str, phase: int,
# @count_calls: count invocations (used to test recursion guard)
_call_count: int = 0
def count_calls(ctx: t.CPtr, func_name: str, phase: int,
args_ptr: t.CPtr,
ret_ptr: t.CPtr,
decor_args_ptr: t.CPtr) -> int | t.CExport:
export def count_calls(ctx: rawptr, func_name: str, phase: int,
args_ptr: rawptr,
ret_ptr: rawptr,
decor_args_ptr: rawptr) -> int:
global _call_count
if phase == 0:
_call_count = _call_count + 1
@@ -93,50 +92,43 @@ def count_calls(ctx: t.CPtr, func_name: str, phase: int,
# --- Test 1: single @log ---
@log
def add(a: int, b: int) -> int | t.CExport:
export def add(a: int, b: int) -> int:
return a + b
# --- Test 2: chained @log @trace (log(trace(f))) ---
@log
@trace
def multiply(a: int, b: int) -> int | t.CExport:
export def multiply(a: int, b: int) -> int:
return a * b
# --- Test 3: @log on void function ---
@log
def greet(name: str) -> void | t.CExport:
export def greet(name: str):
printf("Hello, %s!\n", name)
# --- Test 4: @log on no-arg function ---
@log
def get_value() -> int | t.CExport:
export def get_value() -> int:
return 42
# --- Test 5: @timing ---
@timing
export def compute(x: int) -> int:
return x * x + 1
# --- Test 6: @repeat(3) flow hijack ---
@repeat(3)
export def echo(msg: str):
printf(" echo: %s\n", msg)
# --- Test 7: chained @timing @log ---
@timing
@log
export def power(base: int, exp: int) -> int:
@@ -147,42 +139,37 @@ export def power(base: int, exp: int) -> int:
# --- Test 8: @skip flow hijack ---
@skip
def dangerous() -> int | t.CExport:
export def dangerous() -> int:
printf("This should NOT be printed!\n")
return 999
# --- Test 9: @repeat(3) with return value ---
@repeat(3)
def accumulate(x: int) -> int | t.CExport:
export def accumulate(x: int) -> int:
printf(" accumulate(%d)\n", x)
return x * 10
# --- Test 10: recursion guard, @count_calls on recursive fn ---
@count_calls
def factorial(n: int) -> int | t.CExport:
export def factorial(n: int) -> int:
if n <= 1:
return 1
return n * factorial(n - 1)
# --- Test 11: @log on recursive fib ---
@log
def fib(n: int) -> int | t.CExport:
export def fib(n: int) -> int:
if n <= 1:
return n
return fib(n - 1) + fib(n - 2)
# --- main ---
def main() -> int | t.CExport:
export def main() -> int:
testcheck.begin("Decorator Test v4")
# Test 1: single @log
+1 -2
View File
@@ -1,4 +1,3 @@
import t
import stdio
import testcheck
import remote
@@ -15,7 +14,7 @@ def local_quad(a: int, b: int = 10, c: int = 20, d: int = 30) -> int:
return a + b * 100 + c * 10000 + d * 1000000
def main() -> int:
export def main() -> int:
testcheck.begin("DefaultArgTest: default / named / out-of-order arguments")
# Same-module defaults
-3
View File
@@ -1,6 +1,3 @@
import t
# Cross-module: single trailing default (mirrors write in includes/json/__writer.vp)
def one(x: int, cap: sizet = 4096) -> sizet:
return cap
+46 -51
View File
@@ -1,5 +1,3 @@
import t, c
from t import CInt, CInt32T, CUInt32T, CUInt64T, CFloat64T, CPtr, CChar, CDefine, CUInt16T
import viperlib
import stdlib
import platmacro
@@ -24,22 +22,19 @@ define DISABLED = 0
define PAGE_SIZE = 4096
define BUFFER_LEN = 256
CODE_SEG: t.CDefine | uint16 = 0x08
DATA_SEG: t.CDefine | uint16 = 0x10
STACK_SEG: t.CDefine | uint16 = 0x20
define CODE_SEG: uint16 = 0x08
define DATA_SEG: uint16 = 0x10
define STACK_SEG: uint16 = 0x20
def MAKE_FLAG(bit: CInt32T) -> t.CDefine:
return 1 << bit
define MAKE_FLAG(bit: int32) -> int32: return 1 << bit
def CLAMP(x: CInt32T, lo: CInt32T, hi: CInt32T) -> t.CDefine:
if x < lo:
return lo
if x > hi:
return hi
define CLAMP(x: int32, lo: int32, hi: int32) -> int32:
if x < lo: return lo
if x > hi: return hi
return x
def test_basic_define() -> CInt:
def test_basic_define() -> int:
print(MAX_SIZE)
print(MIN_VAL)
print(MAX_VAL)
@@ -47,20 +42,20 @@ def test_basic_define() -> CInt:
print(SHIFT_BITS)
return 0
def test_define_arithmetic() -> CInt:
a: CInt32T = 10
b: CInt32T = a + MAX_SIZE
def test_define_arithmetic() -> int:
a: int32 = 10
b: int32 = a + MAX_SIZE
print(b)
c_val: CInt32T = (a << SHIFT_BITS) & MASK_BYTE
c_val: int32 = (a << SHIFT_BITS) & MASK_BYTE
print(c_val)
d: CInt32T = MAX_VAL - MIN_VAL
d: int32 = MAX_VAL - MIN_VAL
print(d)
e: CInt32T = PAGE_SIZE / 4
e: int32 = PAGE_SIZE / 4
print(e)
return 0
def test_define_conditional() -> CInt:
mode: CInt32T = ENABLED
def test_define_conditional() -> int:
mode: int32 = ENABLED
if mode == ENABLED:
print(1)
else:
@@ -69,7 +64,7 @@ def test_define_conditional() -> CInt:
print(0)
else:
print(1)
val: CInt32T = 50
val: int32 = 50
if val > MAX_VAL:
print(1)
else:
@@ -80,8 +75,8 @@ def test_define_conditional() -> CInt:
print(0)
return 0
def test_define_loop() -> CInt:
i: CInt32T = 0
def test_define_loop() -> int:
i: int32 = 0
while i < MAX_VAL:
i = i + 1
if i > 10:
@@ -95,16 +90,16 @@ def test_define_loop() -> CInt:
print(i)
return 0
def test_typed_define() -> CInt:
seg: CUInt16T = CODE_SEG | DATA_SEG | STACK_SEG
def test_typed_define() -> int:
seg: uint16 = CODE_SEG | DATA_SEG | STACK_SEG
print(seg)
cs: CUInt16T = CODE_SEG
cs: uint16 = CODE_SEG
print(cs)
ds: CUInt16T = DATA_SEG
ds: uint16 = DATA_SEG
print(ds)
return 0
def test_define_function() -> CInt:
def test_define_function() -> int:
flag0 = MAKE_FLAG(0)
print(flag0)
flag3 = MAKE_FLAG(3)
@@ -113,7 +108,7 @@ def test_define_function() -> CInt:
print(flag7)
return 0
def test_define_clamp() -> CInt:
def test_define_clamp() -> int:
v1 = CLAMP(50, 0, 100)
print(v1)
v2 = CLAMP(-10, 0, 100)
@@ -122,24 +117,24 @@ def test_define_clamp() -> CInt:
print(v3)
return 0
def test_define_string() -> CInt:
buf: CChar | CPtr = CPtr(stdlib.malloc(BUFFER_LEN))
def test_define_string() -> int:
buf: str = stdlib.malloc(BUFFER_LEN)
viperlib.snprintf(buf, BUFFER_LEN, "MAX_SIZE=%d PAGE=%d MASK=0x%x", MAX_SIZE, PAGE_SIZE, MASK_BYTE)
print(buf)
stdlib.free(buf)
return 0
def test_define_combined() -> CInt:
flags: CUInt32T = MAKE_FLAG(0) | MAKE_FLAG(1) | MAKE_FLAG(2)
def test_define_combined() -> int:
flags: uint32 = MAKE_FLAG(0) | MAKE_FLAG(1) | MAKE_FLAG(2)
print(flags)
shifted: CUInt32T = MASK_BYTE << SHIFT_BITS
shifted: uint32 = MASK_BYTE << SHIFT_BITS
print(shifted)
total: CUInt32T = PAGE_SIZE + BUFFER_LEN
total: uint32 = PAGE_SIZE + BUFFER_LEN
print(total)
return 0
def test_cif_basic() -> CInt:
def test_cif_basic() -> int:
cif ENABLED:
print(1)
celse:
@@ -158,7 +153,7 @@ def test_cif_basic() -> CInt:
print(1)
return 0
def test_cif_elif_else() -> CInt:
def test_cif_elif_else() -> int:
# A cif chain can only be pruned at compile time, so the chain selector must be a CDefine
# constant (a runtime variable is rejected).
define VAL = 2
@@ -178,7 +173,7 @@ def test_cif_elif_else() -> CInt:
print(VAL)
return 0
def test_cifdef_cifndef() -> CInt:
def test_cifdef_cifndef() -> int:
cif defined(MAX_SIZE):
print(MAX_SIZE)
celse:
@@ -197,7 +192,7 @@ def test_cifdef_cifndef() -> CInt:
print(1)
return 0
def test_cif_platform() -> CInt:
def test_cif_platform() -> int:
cif defined(_WIN32):
print(1)
celse:
@@ -214,7 +209,7 @@ def test_cif_platform() -> CInt:
print(0)
return 0
def test_cif_nested() -> CInt:
def test_cif_nested() -> int:
cif ENABLED:
cif MAX_SIZE > 512:
print(1)
@@ -228,7 +223,7 @@ def test_cif_nested() -> CInt:
print(0)
return 0
def test_cif_expr() -> CInt:
def test_cif_expr() -> int:
cif MASK_BYTE & 0x0F:
print(1)
celse:
@@ -247,7 +242,7 @@ def test_cif_expr() -> CInt:
print(0)
return 0
def test_platmacro_platform() -> CInt:
def test_platmacro_platform() -> int:
cif defined(platmacro.IS_WINDOWS):
print(1)
celse:
@@ -266,7 +261,7 @@ def test_platmacro_platform() -> CInt:
print(0)
return 0
def test_platmacro_sizes() -> CInt:
def test_platmacro_sizes() -> int:
print(platmacro.PTR_SIZE)
print(platmacro.SIZEOF_INT)
print(platmacro.SIZEOF_LONG)
@@ -275,7 +270,7 @@ def test_platmacro_sizes() -> CInt:
print(platmacro.CACHE_LINE_SIZE)
return 0
def test_platmacro_endian() -> CInt:
def test_platmacro_endian() -> int:
cif platmacro.IS_LITTLE_ENDIAN == 1:
print(1)
celse:
@@ -290,7 +285,7 @@ def test_platmacro_endian() -> CInt:
print(0)
return 0
def test_platmacro_features() -> CInt:
def test_platmacro_features() -> int:
cif platmacro.HAS_SSE2 == 1:
print(1)
celse:
@@ -305,7 +300,7 @@ def test_platmacro_features() -> CInt:
print(0)
return 0
def test_platmacro_align() -> CInt:
def test_platmacro_align() -> int:
print(platmacro.ALIGNOF_INT)
print(platmacro.ALIGNOF_PTR)
print(platmacro.ALIGNOF_DOUBLE)
@@ -315,7 +310,7 @@ def test_platmacro_align() -> CInt:
print(0)
return 0
def test_cifdef_cross_module() -> CInt:
def test_cifdef_cross_module() -> int:
cif defined(platmacro.IS_WINDOWS):
cif platmacro.PTR_SIZE == 8:
print(64)
@@ -333,7 +328,7 @@ def test_cifdef_cross_module() -> CInt:
print(0)
return 0
def test_cifdef_guard() -> CInt:
def test_cifdef_guard() -> int:
define MY_HEADER_GUARD = 1
cif not defined(MY_HEADER_GUARD):
print(0)
@@ -345,7 +340,7 @@ def test_cifdef_guard() -> CInt:
print(0)
return 0
def test_cifdef_undefined() -> CInt:
def test_cifdef_undefined() -> int:
cif not defined(NONEXISTENT_MACRO_ABC):
print(1)
celse:
@@ -360,7 +355,7 @@ def test_cifdef_undefined() -> CInt:
print(1)
return 0
def test_cifdef_complex() -> CInt:
def test_cifdef_complex() -> int:
cif defined(platmacro.IS_WINDOWS) and platmacro.PTR_SIZE == 8:
print(1)
celse:
+21 -23
View File
@@ -1,7 +1,5 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CExport
import stdio
import stdlib
import string
@@ -9,7 +7,7 @@ import memhub
import testcheck
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
@@ -31,11 +29,11 @@ def main() -> CInt | CExport:
# dict int values are stored as i32; reading back requires a typed pointer
# because c.Deref uses the pointee width (i8* always reads 1 byte).
p1: t.CPtr = d["alpha"]
p1: rawptr = d["alpha"]
stdio.printf("p1=%p\n", p1)
p2: t.CPtr = d["beta"]
p2: rawptr = d["beta"]
stdio.printf("p2=%p\n", p2)
p3: t.CPtr = d["gamma"]
p3: rawptr = d["gamma"]
stdio.printf("p3=%p\n", p3)
v1: int = *(int*)(p1)
stdio.printf("v1=%d\n", v1)
@@ -49,7 +47,7 @@ def main() -> CInt | CExport:
# === Test 2: update existing key ===
testcheck.section("Test 2: 更新已有键")
d.set_int("beta", 99)
p2b: t.CPtr = d["beta"]
p2b: rawptr = d["beta"]
v2b: int = *(int*)(p2b)
stdio.printf("beta(updated)=%d\n", v2b)
testcheck.check(v2b == 99, "dict update OK", "dict update FAILED")
@@ -57,10 +55,10 @@ def main() -> CInt | CExport:
# === Test 3: get with default ===
testcheck.section("Test 3: get with default")
gv: t.CPtr = d.get("missing", None)
gv: rawptr = d.get("missing", None)
testcheck.check(gv == None, "dict get missing OK (None)", "dict get missing FAILED")
gp: t.CPtr = d.get("alpha", None)
gp: rawptr = d.get("alpha", None)
ga: int = *(int*)(gp)
stdio.printf("get(alpha)=%d\n", ga)
testcheck.check(ga == 10, "dict get existing OK", "dict get existing FAILED")
@@ -77,7 +75,7 @@ def main() -> CInt | CExport:
testcheck.section("Test 5: 迭代器 for key in dict")
iter_count: int = 0
for key in d:
kp: t.CPtr = d[key]
kp: rawptr = d[key]
val: int = *(int*)(kp)
stdio.printf("dict[%s]=%d\n", key, val)
iter_count += 1
@@ -93,9 +91,9 @@ def main() -> CInt | CExport:
stdio.printf("d2 len=%lu\n", n2)
testcheck.check(n2 == 3, "dict set_str len OK (3)", "dict set_str len FAILED")
name_p: t.CPtr = d2["name"]
city_p: t.CPtr = d2["city"]
lang_p: t.CPtr = d2["lang"]
name_p: rawptr = d2["name"]
city_p: rawptr = d2["city"]
lang_p: rawptr = d2["lang"]
name: str = name_p
city: str = city_p
lang: str = lang_p
@@ -109,7 +107,7 @@ def main() -> CInt | CExport:
testcheck.section("Test 7: dict 迭代 (str values)")
str_iter_count: int = 0
for k in d2:
svp: t.CPtr = d2[k]
svp: rawptr = d2[k]
sv: str = svp
stdio.printf("d2[%s]=%s\n", k, sv)
str_iter_count += 1
@@ -129,14 +127,14 @@ def main() -> CInt | CExport:
# verify a few values
k5: str = stdlib.malloc(16)
stdio.sprintf(k5, "key5")
p5: t.CPtr = d3[k5]
p5: rawptr = d3[k5]
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]
p15: rawptr = d3[k15]
v15: int = *(int*)(p15)
stdio.printf("d3[key15]=%d\n", v15)
testcheck.check(v15 == 1500, "dict expand key15 OK", "dict expand key15 FAILED")
@@ -159,9 +157,9 @@ def main() -> CInt | CExport:
testcheck.section("Test 10: JSON loads")
jd2: dict = dict(bd)
jd2.loads(pool, "{\"x\":1,\"y\":2,\"z\":3}")
xp: t.CPtr = jd2["x"]
yp: t.CPtr = jd2["y"]
zp: t.CPtr = jd2["z"]
xp: rawptr = jd2["x"]
yp: rawptr = jd2["y"]
zp: rawptr = jd2["z"]
xv: int = *(int*)(xp)
yv: int = *(int*)(yp)
zv: int = *(int*)(zp)
@@ -189,8 +187,8 @@ def main() -> CInt | CExport:
stdio.printf("round-trip dump: %s\n", rt_str)
rt2: dict = dict(bd)
rt2.loads(pool, rt_str)
rta_p: t.CPtr = rt2["a"]
rtb_p: t.CPtr = rt2["b"]
rta_p: rawptr = rt2["a"]
rtb_p: rawptr = rt2["b"]
rta: int = *(int*)(rta_p)
rtb: int = *(int*)(rtb_p)
stdio.printf("round-trip: a=%d b=%d\n", rta, rtb)
@@ -206,8 +204,8 @@ def main() -> CInt | CExport:
outer.set_dict("sub", inner)
sub: dict* = outer["sub"]
sa_p: t.CPtr = sub["a"]
sb_p: t.CPtr = sub["b"]
sa_p: rawptr = sub["a"]
sb_p: rawptr = sub["b"]
sa: int = *(int*)(sa_p)
sb: int = *(int*)(sb_p)
stdio.printf("nested: sub.a=%d sub.b=%d\n", sa, sb)
-2
View File
@@ -1,7 +1,5 @@
import t
import stdio
import string
import c
import testcheck
import remote
-3
View File
@@ -1,6 +1,3 @@
import t
def remote_func() -> int:
"Remote function docstring."
return 0
+3 -8
View File
@@ -1,5 +1,3 @@
import t
import t as tt
import stdio
import testcheck
@@ -15,17 +13,14 @@ from t import CChar, CPtr
# Test 1: from t import CEnum as en; class X(en)
# ============================================================
enum Color:
Red = 0
Green = 1
Blue = 2
Red, Green, Blue
# ============================================================
# Test 2: import t as tt; class X(tt.CEnum)
# ============================================================
enum Status:
Ok = 0
Error = 1
Ok, Error
# ============================================================
@@ -90,7 +85,7 @@ val: myint = 42
# Test 8: BigEndian byte order
class NetHeader:
magic: int | t.BigEndian
length: t.CShort | t.BigEndian
length: short | t.BigEndian
normal: int
+11 -12
View File
@@ -1,10 +1,9 @@
import testcheck
import t
# 大小端字节序专项:
# · 标记 `t.BigEndian` 的槽位,在(默认的)小端目标上必须以**大端字节序列**存放;
# · 标记 `t.LittleEndian` 的槽位与目标序一致,按目标序存放;
# · 标记 `bigend` 的槽位,在(默认的)小端目标上必须以**大端字节序列**存放;
# · 标记 `littlend` 的槽位与目标序一致,按目标序存放;
# · 无标记 = native,不参与任何交换。
# 因此本测试既校验「读写成对交换」的语义不变式(round-trip),
# 又**直接检查内存里的字节序列** —— 只有后者能真正证明交换发生了
@@ -19,7 +18,7 @@ def read_byte(p: rawptr, i: int) -> int:
def test_big_endian_local() -> None:
"""大端局部变量:内存字节必须是 12 34 56 78(MSB 在前),读回值不变。"""
testcheck.section("BigEndian local variable")
x: t.CInt32T | t.BigEndian = 0x12345678
x: bigend int32 = 0x12345678
px: rawptr = rawptr(&x)
testcheck.check(read_byte(px, 0) == 0x12, "BigEndian memory byte[0] = 0x12 (MSB first)", "expect 0x12")
testcheck.check(read_byte(px, 1) == 0x34, "BigEndian memory byte[1] = 0x34", "expect 0x34")
@@ -31,7 +30,7 @@ def test_big_endian_local() -> None:
def test_little_endian_local() -> None:
"""小端局部变量:小端目标上与目标序一致,内存字节是 78 56 34 12(LSB 在前)。"""
testcheck.section("LittleEndian local variable")
y: t.CInt32T | t.LittleEndian = 0x12345678
y: littlend int32 = 0x12345678
py: rawptr = rawptr(&y)
testcheck.check(read_byte(py, 0) == 0x78, "LittleEndian memory byte[0] = 0x78 (LSB first)", "expect 0x78")
testcheck.check(read_byte(py, 3) == 0x12, "LittleEndian memory byte[3] = 0x12", "expect 0x12")
@@ -41,8 +40,8 @@ def test_little_endian_local() -> None:
def test_be_le_differ() -> None:
"""同一值分别按大端/小端存放,内存字节序列必须互为反转。"""
testcheck.section("BigEndian vs LittleEndian memory layout")
a: t.CInt32T | t.BigEndian = 0x22334455
b: t.CInt32T | t.LittleEndian = 0x22334455
a: bigend int32 = 0x22334455
b: littlend int32 = 0x22334455
pa: rawptr = rawptr(&a)
pb: rawptr = rawptr(&b)
testcheck.check(read_byte(pa, 0) == read_byte(pb, 3), "BE byte[0] == LE byte[3]", "expect reversed byte order")
@@ -53,9 +52,9 @@ def test_be_le_differ() -> None:
class NetHeader:
"""经典用法:结构体成员带字节序标记(对齐 TransPyC 文档里的 NetHeader)。"""
magic: t.CInt32T | t.BigEndian
length: t.CInt16T | t.BigEndian
body: t.CInt32T
magic: bigend int32
length: littlend int16
body: int32
def test_struct_field_roundtrip() -> None:
@@ -75,11 +74,11 @@ def test_struct_field_roundtrip() -> None:
def test_repeated_write() -> None:
"""反复写入不同值,读回始终正确(交换必须成对且不残留)。"""
testcheck.section("Repeated writes")
x: t.CInt32T | t.BigEndian = 0
x: bigend int32 = 0
i: int = 0
ok: int = 1
for i in range(int(4)):
v: t.CInt32T = t.CInt32T(0x10000000 * (i + 1))
v: int32 = int32(0x10000000 * (i + 1))
x = v
if x != v:
ok = 0
+18 -23
View File
@@ -1,45 +1,40 @@
import t, c
from t import CInt, CPtr, CChar, CInt32T, CExport
import viperlib
import stdlib
class Color(t.CEnum):
Red = 0
Green = 1
Blue = 2
enum Color:
Red, Green, Blue
class Option(t.REnum):
renum Option:
class Some:
value: CInt
value: int
Empty = 1
class Result(t.REnum):
renum Result:
class Ok:
value: CInt
value: int
class Err:
msg: char | CPtr
msg: str
class GeoShape(t.REnum):
renum GeoShape:
class GCircle:
radius: CInt
radius: int
class GRect:
w: CInt
h: CInt
w: int
h: int
class GPoint:
x: CInt
y: CInt
x: int
y: int
def enum_main() -> CInt:
buf: CChar | CPtr = CPtr(stdlib.malloc(256))
def enum_main() -> int:
buf: str = stdlib.malloc(256)
c1: CInt = Color.Red
c2: CInt = Color.Green
c3: CInt = Color.Blue
c1: int = Color.Red
c2: int = Color.Green
c3: int = Color.Blue
viperlib.snprintf(buf, 256, "CEnum: Red=%d Green=%d Blue=%d", c1, c2, c3)
print(buf)
+1 -2
View File
@@ -1,9 +1,8 @@
import t, c
import testcheck
import enumtest
def main() -> int | t.CExport:
export def main() -> int:
testcheck.begin("EnumTest: 枚举类型测试")
testcheck.section("Enum")
enumtest.enum_main()
+1 -3
View File
@@ -1,14 +1,12 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CExport
import stdio
import stdlib
import string
import testcheck
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
-3
View File
@@ -1,6 +1,3 @@
from stdint import *
import t, c
import stdio
import testcheck
+3 -13
View File
@@ -1,5 +1,3 @@
import t
import stdio
import testcheck
@@ -7,17 +5,9 @@ import testcheck
# Three declarations plus main; each must emit exactly one declare.
# Test 1: t.CExtern | t.CExport - external declaration (pass body)
# Translator must emit declare, not define.
def ExternalDecl(x: int) -> int | t.CExtern | t.CExport: pass
# Test 2: t.State - state declaration (same as CExtern | CExport)
def StateDecl(x: int) -> int | t.State: pass
# Test 3: t.State returning void
def StateVoidDecl() -> t.State: pass
extern def ExternalDecl(x: int) -> int
extern def StateDecl(x: int) -> int
extern def StateVoidDecl()
def test_extern_decl():
+2 -4
View File
@@ -1,7 +1,5 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CExport
import _fakeduck
import stdio
import stdlib
@@ -11,7 +9,7 @@ import testcheck
import _withcontent
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
@@ -19,7 +17,7 @@ def main() -> CInt | CExport:
a: str = "Hello"
# Type base class: str calls Type.type_id()
tid: CInt = a.type_id()
tid: int = a.type_id()
if tid == 99:
stdio.printf("Type OK: a.type_id() = %d\n", tid)
+3 -6
View File
@@ -1,12 +1,9 @@
import t, c
from t import CInt, CInt32T, CUInt32T, CPtr, CChar, CExport
from stdint import *
import stdlib
import viperlib
import win32.win32base
import win32.win32file
import win32.win32console
import win32.fileio
from win32.fileio import File, FileW, MODE, FRESULT, SEEK_SET, SEEK_CUR, SEEK_END
@@ -39,10 +36,10 @@ def fileio_main():
viperlib.snprintf(write_buf, BUF_SIZE, "Hello from TransPyC Win32 FileIO!\nLine 2: %d + %d = %d\n", 10, 20, 30)
write_len: ULONG = 0
i: CInt = 0
i: int = 0
ch: bytes = write_buf
while i < BUF_SIZE:
if CInt(*ch) == 0:
if *ch == 0:
break
write_len = write_len + 1
i = i + 1
@@ -82,7 +79,7 @@ def fileio_main():
read_ptr: bytes = read_buf
read_ptr = read_ptr + read_len
c.DerefAs(read_ptr, 0)
*read_ptr = 0
print("--- File content ---")
print(read_buf)
print("--- End ---")
+1 -2
View File
@@ -1,9 +1,8 @@
import t, c
import testcheck
import fileiotest
def main() -> int | t.CExport:
export def main() -> int:
testcheck.begin("FileIoTest: Win32 FileIO 测试")
testcheck.section("Win32 FileIO")
fileiotest.fileio_main()
-3
View File
@@ -1,8 +1,5 @@
import t
import c
import stdio
import stdlib
import string
import memhub
import testcheck
+1 -2
View File
@@ -1,5 +1,4 @@
from stdint import *
import t, c
import ctraits
import stdio
import testcheck
@@ -15,7 +14,7 @@ export def main() -> int:
b += 1
print(b-11)
l: t.CArray[u64] = [0, 43, 2, 3, 4]
l: []u64 = [0, 43, 2, 3, 4]
l[0] = 1000
for i in l:
stdio.printf("%llu\n", i)
+1 -5
View File
@@ -1,5 +1,3 @@
import t
import stdio
import testcheck
from linkedlist import GSListNode
@@ -7,9 +5,7 @@ from linkedlist import GSListNode
# G3: test F-bounded polymorphism.
# class Node(GSListNode[Node]) inherits a generic base specialized on itself.
# ============================================================
@t.NoVTable
class Node(GSListNode[Node]):
novirtual class Node(GSListNode[Node]):
value: int
def __init__(self):
-3
View File
@@ -1,6 +1,3 @@
import t
import stdio
import stdlib
import memhub
from g4node import G4Node, new_g4node
-4
View File
@@ -1,7 +1,3 @@
import t
import stdio
import stdlib
import memhub
from g4node import G4Node, new_g4node
-4
View File
@@ -1,7 +1,3 @@
import t
import stdio
import stdlib
import memhub
from g4node import G4Node, new_g4node
-1
View File
@@ -1,4 +1,3 @@
import t
import stdio
import testcheck
import stdlib
+2 -6
View File
@@ -1,5 +1,3 @@
import t
import stdio
import testcheck
import stdlib
import memhub
@@ -14,8 +12,7 @@ from linkedlist import GSListNode, GSList
# G5Node: inherits GSListNode[G5Node] (Phase2 path, correct specialization)
@t.NoVTable
class G5Node(GSListNode[G5Node]):
novirtual class G5Node(GSListNode[G5Node]):
Value: int
def __init__(self):
@@ -27,8 +24,7 @@ class G5Node(GSListNode[G5Node]):
# field access; a pool factory allocates it, avoiding dangling stack pointers.
define GSLIST_SIZE = 24 # Head(8) + Tail(8) + Count(8)
@t.NoVTable
class G5ListWrapper:
novirtual class G5ListWrapper:
List: GSList[G5Node]*
def __init__(self, pool: memhub.MemBuddy*):
-2
View File
@@ -1,5 +1,3 @@
import t, c
import stdio
import testcheck
import atom
+1 -3
View File
@@ -1,5 +1,3 @@
import t
import stdio
import testcheck
import stdlib
import memhub
@@ -7,7 +5,7 @@ from conflict_node import Value
# G7: global variable 'Value' collides with class 'Value'
# Variable registration overrides the struct symbol, so struct body setup is skipped.
Value: t.CPtr = None
Value: rawptr = None
def test_value_struct_fields():
+9 -11
View File
@@ -1,7 +1,5 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CPtr, CChar, CInt32T, CUInt64T, CFloat64T, CExport, State
import viperlib
import stdlib
import testcheck
@@ -12,11 +10,11 @@ import testcheck
def add[T](a: T, b: T) -> T:
return a + b
def add_u64[T](a: T, b: T, c: CUInt64T) -> T:
def add_u64[T](a: T, b: T, c: u64) -> T:
return a + b + T(c)
def fxi[T1, T2](a: T1, b: T2) -> T1:
return a + fxi2(a, b, CUInt64T(178900))
return a + fxi2(a, b, u64(178900))
def fxi2[T1, T2, T3](a: T1, b: T2, c: T3) -> T1:
return a + T1(b) + T1(c)
@@ -59,29 +57,29 @@ class Calculator[T]():
class Container[T]():
value: T
flag: CInt32T
flag: u32
def __init__(self, v: T):
self.value = T(v)
self.flag = CInt32T(1)
self.flag = u32(1)
def get_value(self) -> T:
return self.value
def get_flag(self) -> CInt32T:
def get_flag(self) -> u32:
return self.flag
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
testcheck.begin("GenericOopTest: 泛型专项测试")
buf: CChar | CPtr = CPtr(stdlib.malloc(256))
buf: char = stdlib.malloc(256)
# === Basic generic functions ===
testcheck.section("基础函数泛型")
print(add(3, 5))
print(add(1.5, 2.5))
print(add_u64(1, 2, CUInt64T(3000000000000000)))
print(add_u64(1, 2, u64(3000000000000000)))
print(fxi(0.2, 6))
print(wrap_add(10, 20))
print(double_add(5, 7))
@@ -118,7 +116,7 @@ def main() -> CInt | CExport:
# === New cast syntax (t1|t2)(x) ===
testcheck.section("新语法类型强转 (t1|t2)(x)")
val_i64: CUInt64T = CUInt64T(42)
val_i64: u64 = u64(42)
val_i32 = (int)(val_i64)
print(val_i32)
+2 -4
View File
@@ -1,5 +1,3 @@
import t
import stdio
import testcheck
# ============================================================
@@ -85,7 +83,7 @@ def test_generic_pair():
# ============================================================
def test_fixed_array():
testcheck.section("Test 6: list[T, N] fixed array")
arr: t.CArray[int, 5] = [0]
arr: [5]int = [0]
for i in range(5):
arr[i] = i * 10
total: int = 0
@@ -99,7 +97,7 @@ def test_fixed_array():
# ============================================================
def test_char_array():
testcheck.section("Test 7: list[t.CChar, N] char array")
buf: t.CArray[char, 32] = [0]
buf: [32]char = [0]
buf[0] = 72 # H
buf[1] = 105 # i
buf[2] = 0
+3 -5
View File
@@ -1,6 +1,4 @@
import t
import stdio
import c
import testcheck
# ============================================================
@@ -124,7 +122,7 @@ def test_generic_range():
# ============================================================
# Test 6: generic function summing a fixed-size array argument
# ============================================================
def array_sum(arr: t.CArray[int, 8], n: int) -> int:
def array_sum(arr: [8]int, n: int) -> int:
result: int = 0
for i in range(n):
result += arr[i]
@@ -132,7 +130,7 @@ def array_sum(arr: t.CArray[int, 8], n: int) -> int:
def test_generic_array_sum():
testcheck.section("Test 6: array sum")
arr: t.CArray[int, 8] = [0]
arr: [8]int = [0]
for i in range(8):
arr[i] = (i + 1) * 10
s: int = array_sum(arr, 8)
@@ -160,7 +158,7 @@ def test_generic_max_three():
# Test 8: generic container class with methods
# ============================================================
class Container[T]():
values: t.CArray[int, 8]
values: [8]int
size: int
def __init__(self):
-2
View File
@@ -1,5 +1,3 @@
import t
import stdio
import testcheck
# Test 1: generic function with explicit type arg - basic call
+11 -13
View File
@@ -1,8 +1,6 @@
import t
import stdio
import testcheck
# Test 1: generic class with explicit type arg - Box[t.CInt](v)
# Test 1: generic class with explicit type arg - Box[int](v)
class Box[T]():
value: T
@@ -16,12 +14,12 @@ class Box[T]():
self.value = T(v)
def test_explicit_box():
testcheck.section("Test 1: Box[t.CInt](42)")
testcheck.section("Test 1: Box[int](42)")
b = Box[int](42)
v: int = b.get()
testcheck.check(v == 42, "Box[t.CInt](42).get() = 42", "expect 42")
testcheck.check(v == 42, "Box[int](42).get() = 42", "expect 42")
# Test 2: generic class with explicit type arg - Pair[t.CInt, t.CInt]
# Test 2: generic class with explicit type arg - Pair[int, int]
class Pair[T1, T2]():
first: T1
second: T2
@@ -34,10 +32,10 @@ class Pair[T1, T2]():
return int(self.first) + int(self.second)
def test_explicit_pair():
testcheck.section("Test 2: Pair[t.CInt, t.CInt](10, 20)")
testcheck.section("Test 2: Pair[int, int](10, 20)")
p = Pair[int, int](10, 20)
r: int = p.sum_as_int()
testcheck.check(r == 30, "Pair[t.CInt,t.CInt](10,20).sum = 30", "expect 30")
testcheck.check(r == 30, "Pair[int,int](10,20).sum = 30", "expect 30")
# Test 3: generic class explicit + inferred mixed
class Wrapper[T]():
@@ -57,7 +55,7 @@ def test_mixed_generic_class():
w2 = Wrapper(200)
r1: int = w1.get()
r2: int = w2.get()
testcheck.check(r1 == 100 and r2 == 200, "Wrapper[t.CInt](100)=100 Wrapper(200)=200", "expect 100 200")
testcheck.check(r1 == 100 and r2 == 200, "Wrapper[int](100)=100 Wrapper(200)=200", "expect 100 200")
# Test 4: generic class explicit - method calls
class Counter[T]():
@@ -73,21 +71,21 @@ class Counter[T]():
return self.count
def test_explicit_counter():
testcheck.section("Test 4: Counter[t.CInt](0) with methods")
testcheck.section("Test 4: Counter[int](0) with methods")
c = Counter[int](0)
c.increment()
c.increment()
c.increment()
r: int = c.get_count()
testcheck.check(r == 3, "Counter[t.CInt](0) +3 = 3", "expect 3")
testcheck.check(r == 3, "Counter[int](0) +3 = 3", "expect 3")
# Test 5: generic class explicit - set method
def test_explicit_box_set():
testcheck.section("Test 5: Box[t.CInt] set method")
testcheck.section("Test 5: Box[int] set method")
b = Box[int](10)
b.set(99)
v: int = b.get()
testcheck.check(v == 99, "Box[t.CInt].set(99) get = 99", "expect 99")
testcheck.check(v == 99, "Box[int].set(99) get = 99", "expect 99")
def main() -> int:
testcheck.begin("GenericTest4: 泛型结构体手动传类型参数")
+9 -11
View File
@@ -1,7 +1,5 @@
import t, c
import stdio
import stdlib
import string
import testcheck
import hashlib
import binascii
@@ -22,7 +20,7 @@ def default_value_test_function(a: int, b: int = 1):
print(a, b)
def main() -> int | t.CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
@@ -32,7 +30,7 @@ def main() -> int | t.CExport:
testcheck.section("HASHLIB")
plain: str = "hello123"
md5_buf: t.CArray[uint8, hashlib.MD5_DIGEST_LEN]
md5_buf: [hashlib.MD5_DIGEST_LEN]uint8
mctx = hashlib.md5()
mctx.update(plain)
mctx.final(md5_buf)
@@ -40,7 +38,7 @@ def main() -> int | t.CExport:
print_hex(md5_buf, hashlib.MD5_DIGEST_LEN)
testcheck.ok("HASHLIB md5 completed")
sha1_buf: t.CArray[uint8, hashlib.SHA1_DIGEST_LEN]
sha1_buf: [hashlib.SHA1_DIGEST_LEN]uint8
s1ctx = hashlib.sha1()
s1ctx.update(plain)
s1ctx.final(sha1_buf)
@@ -48,7 +46,7 @@ def main() -> int | t.CExport:
print_hex(sha1_buf, hashlib.SHA1_DIGEST_LEN)
testcheck.ok("HASHLIB sha1 completed")
sha256_buf: t.CArray[uint8, hashlib.SHA256_DIGEST_LEN]
sha256_buf: [hashlib.SHA256_DIGEST_LEN]uint8
s2ctx = hashlib.sha256()
s2ctx.update(plain)
s2ctx.final(sha256_buf)
@@ -56,7 +54,7 @@ def main() -> int | t.CExport:
print_hex(sha256_buf, hashlib.SHA256_DIGEST_LEN)
testcheck.ok("HASHLIB sha256 completed")
sha512_buf: t.CArray[uint8, hashlib.SHA512_DIGEST_LEN]
sha512_buf: [hashlib.SHA512_DIGEST_LEN]uint8
s5ctx = hashlib.sha512()
s5ctx.update(plain)
s5ctx.final(sha512_buf)
@@ -69,8 +67,8 @@ def main() -> int | t.CExport:
# ---------- base64 encode/decode tests ----------
testcheck.section("BASE64")
b64_out: t.CArray[char, 256]
b64_dec: t.CArray[uint8, 256]
b64_out: [256]char
b64_dec: [256]uint8
base64.b64encode(plain, b64_out)
print("Base64 编码:", b64_out)
dlen: sizet = base64.b64decode(b64_out, b64_dec)
@@ -106,8 +104,8 @@ def main() -> int | t.CExport:
stdlib.free(uu_out)
testcheck.ok("BINASCII b2a_uu completed")
hqx_in: t.CArray[char, 4] = ['A', 'B', 'C', '\0']
hqx_crc: t.CUnsignedShort = 0
hqx_in: [4]char = ['A', 'B', 'C', '\0']
hqx_crc: ushort = 0
hqx_out: str
unhqx: str
hqx_out, hqx_crc = binascii.b2a_hqx(hqx_in, 3)
+1 -3
View File
@@ -1,7 +1,5 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CExport
import stdio
import stdlib
import string
@@ -10,7 +8,7 @@ import hashtable
import testcheck
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
+131
View File
@@ -0,0 +1,131 @@
import testcheck
# 浮现点:整型“最小宽度”回绕 + i64 移位不收敛(同一族 bug 的四个面)。
# 现场来源:
# ① Gargantua: define V3_POOL_BYTES = V3_POOL_SIZE * 24 + 512(8192*24 被按 i16 算成 0 → 得 512)
# ② vpsdk/window.vp: define WINBUF_MAX_BYTES = 1024 * 1024 * 4(按 i16 → 0;随后内核 memcpy 越界)
# ③ ViperC 自身: `while t != 0: t = t >> 1`(t 为 int64)在生成代码里不收敛 → 编译期死循环
# 注:ViperC 由 TPC 引导,本用例同时用来照 TPC 侧的同源实现。
define V3_POOL_SIZE = 8192
define V3_POOL_BYTES = V3_POOL_SIZE * 24 + 512
def test_static_defines():
"""静态 define 算式必须按**结果值**拓宽,不能按最小宽度回绕。"""
testcheck.section("Test 1: define 算式(静态求值)不按最小宽度回绕")
testcheck.check(V3_POOL_BYTES == 197120, "V3_POOL_SIZE * 24 + 512 == 197120",
"按 i16 回绕会得到 512(8192*24 = 196608 = 0x30000,低 16 位正好为 0)")
def test_runtime_const_expr():
"""运行期纯常量算式同样不能按最小宽度回绕。"""
testcheck.section("Test 2: 运行期纯常量算式不按最小宽度回绕")
v: int = 1024 * 1024 * 4
testcheck.check(v == 4194304, "1024 * 1024 * 4 == 4194304", "按 i16 回绕会得到 0")
def test_i64_shift_value():
"""i64 的 >> 必须是真 64 位移位(移位计数需与左操作数同宽)。"""
testcheck.section("Test 3: i64 >> 的值正确")
x: int64 = 0x30000
y: int64 = x >> 1
testcheck.check(y == 0x18000, "i64 0x30000 >> 1 == 0x18000", "窄移位会保留高位 → 值错")
def test_i64_shift_loop_converges():
"""核心浮现点:i64 右移循环必须收敛。
若 `>>` 的计数没有与左操作数同宽(按最小宽度 i32 发射),只会移低 32 位,
i64 高位永不清零,而 `x != 0` 是全宽比较 → 永不收敛(ViperC 曾在编译期死在这里)。
这里加 200 次上限:出 bug 时以“次数不对”报错,而不是把测试挂死。
"""
testcheck.section("Test 4: i64 右移循环收敛(0x30000 需 18 次归零)")
x: int64 = 0x30000
n: int = 0
while x != 0:
x = x >> 1
n += 1
if n > 200: break
testcheck.check(n == 18, "0x30000 右移 18 次归零", "窄移位则永不归零(次数 > 32 或触发 200 次上限)")
def test_i64_negative_shift():
"""负数形态:钉死 ViperC 编译期死循环的真正机理。
`-196608 >> 1` 是**算术**右移(= -98304);负数直接右移永远停在负数、`!= 0` 永不成立
——这正是当时 ViperC 里 `while t != 0: t = t >> 1`(t 为负)死循环的形态。
这里用 200 次上限把它“有界复现”:m 应为 201(说明是算术右移,永不归零);
若 m 明显更小(例如 ~49)说明按**逻辑**右移处理了负数(把负数当无符号)。
"""
testcheck.section("Test 5: 负数 i64 的算术右移(死循环原形态,有界复现)")
x: int64 = -196608
y: int64 = x >> 1
testcheck.check(y == -98304, "-196608 >> 1 == -98304(算术右移)", "按逻辑右移会得到很大的正数")
w: int64 = -196608
m: int = 0
while w != 0:
w = w >> 1
m += 1
if m > 200: break
testcheck.check(m == 201, "负数直接右移永不归零(触发 200 次上限)", "m 偏小说明被按逻辑右移处理,语义不对")
# 定宽实现必须先取反再数位(本次修复采用),验证它对负数也能收敛
z: int64 = x ^ int64(-1) # ~(-196608) = 196607
n: int = 0
while z != 0:
z = z >> 1
n += 1
if n > 200: break
testcheck.check(n == 18, "~(-196608) = 196607 右移 18 次归零", "先取反再数位应能收敛(ViperC 修复后的写法)")
def test_negative_source():
"""判别:负数来自**负字面量**(一元负号)还是**运算结果** —— 用来定位 TPC 把谁登记成无符号。
TPC 的 `>>` 符号性取自 `var_signedness[name]`(按变量名登记,登记源是某类型串)。
若下面第 1 条 FAIL、第 2 条 PASS ⇒ 是“负字面量”被判成无符号(字面量一元负号路径);
若两条都 FAIL ⇒ 是对“负值”一律按无符号处理。
"""
testcheck.section("Test 6: 负数的来源(字面量 vs 运算)")
b: int64 = -196608 # 一元负号作用于字面量
cb: int64 = b >> 1
# 直接断言裸值:赋值/物化阶段就必须是 -196608(曾被 zext 成 4294770688 = 0x00000000FFFD0000)。
testcheck.check(b == -196608, "负字面量赋值本身正确(b == -196608)",
"FAIL ⇒ 赋值/物化阶段就把 -196608 弄错了")
testcheck.check(cb == -98304, "负**字面量**变量右移仍为算术右移", "FAIL ⇒ 负字面量被登记成无符号")
c: int64 = 0 - 196608 # 由运算产生的负数
cc: int64 = c >> 1
testcheck.check(cc == -98304, "由**运算**得到负数的变量右移为算术右移", "FAIL ⇒ 对负值一律按无符号处理")
def test_explicit_cast_widths():
"""显式强转:加宽保符号(sext)、窄化截断(trunc)——不受“隐式窄化禁止”约束。
现场:TPC 编译 ViperC 时 `LONG(BUF_B)`(sizet/u64 → int32,Windows LLP64 下 LONG 为 32 位)
被判成“隐式窄化禁止”而 FailFastError(TypeGenResolve.vp:1065)。显式转换必须允许 trunc;
加宽必须 sext,否则 `int64(int32(-1))` 会变成 4294967295。
"""
testcheck.section("Test 7: 显式强转的加宽/窄化")
n: sizet = 65536
n32: int32 = int32(n)
testcheck.check(n32 == 65536, "int32(sizet 65536) == 65536(显式窄化=截断)",
"编译失败/FAIL ⇒ 显式窄化被当成隐式窄化拒绝(FailFastError)")
neg: int32 = -1
wide: int64 = int64(neg)
testcheck.check(wide == -1, "int64(int32 -1) == -1(显式加宽保符号)",
"FAIL ⇒ 显式加宽用了 zext,-1 变 4294967295")
def main() -> int:
testcheck.begin("IntWidthTest: 整型常量/移位的最小宽度回绕与 i64 移位收敛")
test_static_defines()
test_runtime_const_expr()
test_i64_shift_value()
test_i64_shift_loop_converges()
test_i64_negative_shift()
test_negative_source()
test_explicit_cast_widths()
return testcheck.end()
+39
View File
@@ -0,0 +1,39 @@
{
"$schema": "https://raw.githubusercontent.com/TermiNexus/TransPyC/main/schemas/project-schema.json",
"name": "IntWidthTest",
"version": "1.0.0",
"source_dir": "./App",
"build_dir": "./__vpcbuild__",
"compiler": {
"cmd": "llc",
"flags": [
"-filetype=obj",
"-relocation-model=pic"
]
},
"linker": {
"cmd": "clang++",
"flags": [
"-lmsvcrt",
"-lucrt",
"-lpthread",
"-lmingwex",
"-lkernel32",
"-luser32"
],
"output": "IntWidthTest.exe"
},
"includes": [
"../../includes"
],
"target": {
"triple": "x86_64-pc-windows-gnu",
"datalayout": "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
},
"options": {
"slice_level": 3,
"sha1_slice_level": 1,
"target": "llvm",
"strict_mode": true
}
}
+11 -21
View File
@@ -1,41 +1,31 @@
import t
from t import CInt
# ============================================================
# Cross-module isinstance test library: classes defined here are imported by
# main.vp to verify vtable comparison resolves across object files.
# ============================================================
@t.CVTable
class Shape:
def area(self) -> CInt:
def area(self) -> int:
return 0
@t.CVTable
class Circle(Shape):
r: CInt
virtual class Circle(Shape):
r: int
def __init__(self, r: CInt):
def __init__(self, r: int):
self.r = r
def area(self) -> CInt:
def area(self) -> int:
return self.r
@t.CVTable
class Square(Shape):
s: CInt
virtual class Square(Shape):
s: int
def __init__(self, s: CInt):
def __init__(self, s: int):
self.s = s
def area(self) -> CInt:
def area(self) -> int:
return self.s
@t.NoVTable
class PlainShape:
tag: CInt
novirtual class PlainShape:
tag: int
+22 -34
View File
@@ -1,8 +1,6 @@
from stdint import *
import t, c
import testcheck
import geom_lib
from t import CInt, CPtr, CExport
# ============================================================
@@ -12,9 +10,7 @@ from t import CInt, CPtr, CExport
# ========== CVTable inheritance ==========
@t.CVTable
class Animal:
virtual class Animal:
Name: str
def __init__(self, name: str):
@@ -24,8 +20,7 @@ class Animal:
return "..."
@t.CVTable
class Dog(Animal):
virtual class Dog(Animal):
def __init__(self, name: str):
self.Name = name
@@ -33,49 +28,42 @@ class Dog(Animal):
return "Woof"
@t.CVTable
class Cat(Animal):
virtual class Cat(Animal):
def speak(self) -> str:
return "Meow"
# ========== multiple inheritance ==========
virtual class A:
a: int
@t.CVTable
class A:
a: CInt
def get_a(self) -> CInt:
def get_a(self) -> int:
return self.a
@t.CVTable
class B:
b: CInt
virtual class B:
b: int
def get_b(self) -> CInt:
def get_b(self) -> int:
return self.b
@t.CVTable
class AB(A, B):
def __init__(self, a: CInt, b: CInt):
virtual class AB(A, B):
def __init__(self, a: int, b: int):
self.a = a
self.b = b
# ========== NoVTable (compile-time) ==========
@t.NoVTable
class Plain:
v: CInt
novirtual class Plain:
v: int
def main() -> CInt | CExport:
export def main() -> int:
testcheck.begin("IsinstanceTest: isinstance 内建函数测试")
# --- 1. self type and subclass -> base ---
d: Dog | CPtr = Dog("dog")
d: Dog* = Dog("dog")
testcheck.check(isinstance(d, Dog) == 1, "isinstance(d, Dog) 自身 OK",
"isinstance(d, Dog) FAILED")
testcheck.check(isinstance(d, Animal) == 1, "isinstance(d, Animal) 子类→基类 OK",
@@ -84,7 +72,7 @@ def main() -> CInt | CExport:
"isinstance(d, Cat) FAILED")
# --- 2. runtime polymorphism: base pointer to subclass object ---
a: Animal | CPtr = (Animal | CPtr)(d)
a: Animal* = Animal*(d)
testcheck.check(isinstance(a, Dog) == 1,
"isinstance(Animal*, Dog 对象) 运行时多态 OK",
"isinstance(Animal*, Dog) FAILED")
@@ -102,7 +90,7 @@ def main() -> CInt | CExport:
"isinstance 元组未命中 FAILED")
# --- 4. multiple inheritance ---
ab: AB | CPtr = AB(1, 2)
ab: AB* = AB(1, 2)
testcheck.check(isinstance(ab, A) == 1, "isinstance(AB, A) 多继承 OK",
"isinstance(AB, A) FAILED")
testcheck.check(isinstance(ab, B) == 1, "isinstance(AB, B) 多继承 OK",
@@ -113,33 +101,33 @@ def main() -> CInt | CExport:
"AB 字段/方法 FAILED")
# --- 5. NoVTable (compile-time static) ---
p: Plain | CPtr = Plain()
p: Plain* = Plain()
p.v = 42
testcheck.check(isinstance(p, Plain) == 1, "isinstance NoVTable 编译时 OK",
"isinstance NoVTable FAILED")
testcheck.check(p.v == 42, "NoVTable 字段正常 OK", "NoVTable 字段 FAILED")
# --- 6. cross-module isinstance (vtable resolved at link time) ---
cc: geom_lib.Circle | CPtr = geom_lib.Circle(5)
cc: geom_lib.Circle* = geom_lib.Circle(5)
testcheck.check(isinstance(cc, geom_lib.Circle) == 1,
"跨模块 isinstance 自身 OK", "跨模块 isinstance 自身 FAILED")
testcheck.check(isinstance(cc, geom_lib.Shape) == 1,
"跨模块 isinstance 子类→基类 OK", "跨模块 isinstance 子类→基类 FAILED")
testcheck.check(isinstance(cc, geom_lib.Square) == 0,
"跨模块 isinstance 不匹配 OK", "跨模块 isinstance 不匹配 FAILED")
sq: geom_lib.Square | CPtr = geom_lib.Square(3)
sq: geom_lib.Square* = geom_lib.Square(3)
testcheck.check(isinstance(sq, geom_lib.Shape) == 1,
"跨模块 Square→Shape OK", "跨模块 Square→Shape FAILED")
testcheck.check(isinstance(sq, geom_lib.Circle) == 0,
"跨模块 Square vs Circle OK", "跨模块 Square vs Circle FAILED")
shp: geom_lib.Shape | CPtr = (geom_lib.Shape | CPtr)(cc)
shp: geom_lib.Shape* = geom_lib.Shape*(cc)
testcheck.check(isinstance(shp, geom_lib.Circle) == 1,
"跨模块运行时多态 OK", "跨模块运行时多态 FAILED")
testcheck.check(shp.area() == 5, "跨模块虚方法分派 OK", "跨模块虚方法分派 FAILED")
testcheck.check(cc.area() == 5, "跨模块 Circle.area OK", "跨模块 Circle.area FAILED")
# --- 7. NoVTable cross-module static ---
ps: geom_lib.PlainShape | CPtr = geom_lib.PlainShape()
ps: geom_lib.PlainShape* = geom_lib.PlainShape()
testcheck.check(isinstance(ps, geom_lib.PlainShape) == 1,
"跨模块 NoVTable 静态 OK", "跨模块 NoVTable 静态 FAILED")
+3 -4
View File
@@ -1,7 +1,8 @@
import t
import stdio
import string
import testcheck
import win32.win32memory
def test_for_in_string():
testcheck.section("Test 1: for-in string iteration")
@@ -15,7 +16,7 @@ def test_for_in_string():
def test_for_in_char_ptr():
testcheck.section("Test 2: for-in char* iteration")
s: char* = "ABC"
chars: t.CArray[int, 4] = [0]
chars: [4]int = [0]
idx: int = 0
for ch in s:
if idx < 3:
@@ -27,7 +28,6 @@ def test_strcpy_for_in():
testcheck.section("Test 3: strcpy using for-in")
src: char* = "test"
# Implement strcpy by hand with for-in.
import win32.win32memory
buf: char* = win32.win32memory.VirtualAlloc(None, 64, 12288, 4)
if uint64(buf) == 0:
stdio.printf("SKIP: VirtualAlloc returned NULL\n")
@@ -42,7 +42,6 @@ def test_strcpy_for_in():
# '==' on pointers compares addresses (C-like); use strcmp for contents.
testcheck.check(string.strcmp(buf, "test") == 0, "strcpy for-in (result=test)", "strcpy for-in (cmp mismatch)")
import win32.win32memory
def main() -> int:
testcheck.begin("IterTest: 指针迭代测试")
-1
View File
@@ -1,4 +1,3 @@
import t, c
from stdint import *
from stdio import printf
import memhub
+11 -13
View File
@@ -1,14 +1,12 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CExport
import stdlib
import stdio
import memhub
import testcheck
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
@@ -24,9 +22,9 @@ def main() -> CInt | CExport:
nums.append(10)
nums.append(20)
nums.append(30)
v0: CInt = nums.get(0)
v1: CInt = nums.get(1)
v2: CInt = nums.get(2)
v0: int = nums.get(0)
v1: int = nums.get(1)
v2: int = nums.get(2)
stdio.printf("v0=%d v1=%d v2=%d\n", v0, v1, v2)
testcheck.check(v0 == 10 and v1 == 20 and v2 == 30,
"append+get OK (10,20,30)", "append+get FAILED")
@@ -40,13 +38,13 @@ def main() -> CInt | CExport:
# === Test 3: set ===
testcheck.section("Test 3: set")
nums.set(1, 99)
v1b: CInt = nums.get(1)
v1b: int = nums.get(1)
stdio.printf("after set(1,99): v1=%d\n", v1b)
testcheck.check(v1b == 99, "set OK (idx1=99)", "set FAILED")
# === Test 4: pop ===
testcheck.section("Test 4: pop")
popped: CInt = nums.pop()
popped: int = nums.pop()
stdio.printf("popped=%d\n", popped)
testcheck.check(popped == 30, "pop OK (30)", "pop FAILED expect 30")
n2: sizet = nums.__len__()
@@ -61,15 +59,15 @@ def main() -> CInt | CExport:
# === Test 6: capacity growth (append past initial capacity 8) ===
testcheck.section("Test 6: 容量增长")
nums2 = list[int](bd)
i: CInt
i: int
for i in range(20):
nums2.append(i * 5)
n4: sizet = nums2.__len__()
stdio.printf("after 20 appends: len=%lu\n", n4)
testcheck.check(n4 == 20, "grow len OK (20)", "grow len FAILED")
ok: CInt = 1
ok: int = 1
for i in range(20):
v: CInt = nums2.get(i)
v: int = nums2.get(i)
if v != i * 5:
stdio.printf("MISMATCH at %d: got %d expect %d\n", i, v, i * 5)
ok = 0
@@ -81,8 +79,8 @@ def main() -> CInt | CExport:
nums2.clear()
nums2.append(100)
nums2.append(200)
va: CInt = nums2.get(0)
vb: CInt = nums2.get(1)
va: int = nums2.get(0)
vb: int = nums2.get(1)
stdio.printf("re-append: va=%d vb=%d\n", va, vb)
testcheck.check(va == 100 and vb == 200, "re-append OK", "re-append FAILED")
-3
View File
@@ -1,6 +1,3 @@
import t, c
define POSMAX = 100
define MAX_RETRY = 5
define BUFFER_SIZE = 256
+8 -6
View File
@@ -1,5 +1,4 @@
import config
import t, c
def ForRangeBasicTest(stop: int):
@@ -153,17 +152,19 @@ def ForWithCaseAndNoBreakTest(n: int):
i: int = 0
result: int = 0
for i in range(n):
match i:
switch i:
case 0:
result += 1
fallthrough
case 1:
result += 2
fallthrough
case 2:
result += 3
result += 10
fallthrough
case _:
result += i
c.NoBreak
print("NoBreak result: ", result)
@@ -189,7 +190,7 @@ def NestedWhileWithMultipleBreakPoints(depth: int, width: int):
if w == 2:
break
if d == 1 and w == 1:
c.Break
break
count += 1
print("Nested break count: ", count)
@@ -349,14 +350,15 @@ def ForWithCaseNoBreakNested(inner_limit: int):
result: int = 0
for i in range(3):
for j in range(inner_limit):
match j:
switch j:
case 0:
result += 1
fallthrough
case 1:
result += 2
fallthrough
case _:
result += 3
c.NoBreak
print("Nested NoBreak result: ", result)
-2
View File
@@ -1,5 +1,3 @@
import t, c
import config
import logic_test
import testcheck
-3
View File
@@ -1,6 +1,3 @@
import t, c
define POSMAX = 100
define MAX_RETRY = 5
define BUFFER_SIZE = 256
-1
View File
@@ -1,5 +1,4 @@
import stdio
import t, c
import config
import test
import testcheck
+7 -8
View File
@@ -1,5 +1,4 @@
import config
import t, c
def AboutSizeTWhileTest(length: sizet):
@@ -80,8 +79,8 @@ def WhileWithElifElseTest(start: int, end: int):
def NestedWhileWithMacrosTest(outer_limit: int, inner_limit: int):
inner: int = 0
total_ops: int = 0
for outer in range(outer_limit):
for inner in range(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
@@ -111,7 +110,7 @@ def ComplexConditionTest(a: int, b: int, c_val: int):
def RetryLoopTest(retry_count: int) -> int:
success: int = 0
for attempt in range(retry_count):
for attempt in range(retry_count):
if attempt < config.MAX_RETRY:
print("Attempt: ", attempt, " less than max")
success = attempt * 2
@@ -183,7 +182,7 @@ def CompoundAssignmentMathTest(a: int, b: int) -> int:
def PowerAndModuloTest(base: int, exponent: int) -> int:
result: int = 1
temp: int = 0
for i in range(exponent):
for i in range(exponent):
result *= base
print("Power: ", result)
temp = result % config.MODULO_DIVISOR
@@ -220,7 +219,7 @@ def MixedArithmeticTest(x: int, y: int, z: int) -> int:
def MathWithWhileLoopTest(start: int, count: int) -> int:
accumulator: int = 0
multiplier: int = config.MATH_SCALE
for idx in range(count):
for idx in range(count):
temp: int = (start + idx) * multiplier
temp = temp + config.MATH_OFFSET
if temp > config.THRESHOLD:
@@ -237,7 +236,7 @@ def ComplexNestedMathTest(a: int, b: int) -> int:
layer3: int = 0
layer1 = (a + b) * config.MATH_SCALE
print("Layer1: ", layer1)
for i in range(config.BIT_RANGE):
for i in range(config.BIT_RANGE):
layer2 += layer1 >> 1
print("Layer2: ", layer2)
layer3 = layer1 + layer2 - config.MATH_OFFSET
@@ -249,7 +248,7 @@ def ComplexNestedMathTest(a: int, b: int) -> int:
def ConditionalMathChainTest(value: int) -> int:
result: int = 0
for step in range(config.LOOP_LIMIT):
for step in range(config.LOOP_LIMIT):
if step < 5:
result += step * config.MATH_SCALE
print("step<5: ", result)
+1 -2
View File
@@ -1,7 +1,6 @@
import t
import stdio
import testcheck
def test_for_loop():
testcheck.section("Test 1: for loop")
sum_val: int = 0
+1 -1
View File
@@ -2,7 +2,7 @@ from stdint import *
import stdio
import string
import stdlib
import w32.fileio as fileio
import win32.fileio as fileio
import memhub
import testcheck
import viperlib
+15 -18
View File
@@ -1,6 +1,4 @@
from stdint import *
import t, c
import stdio
import stdlib
import testcheck
import memhub
@@ -8,7 +6,7 @@ import memhub
# Polymorphism test: call through a MemManager base pointer, verify vtable dispatch
def test_polymorphic(mgr: memhub.MemManager*, size: sizet) -> int:
p: t.CPtr = mgr.alloc(size)
p: rawptr = mgr.alloc(size)
if p is None:
return 0
mgr.free(p)
@@ -17,18 +15,17 @@ def test_polymorphic(mgr: memhub.MemManager*, size: sizet) -> int:
# Test calloc polymorphism: calloc is concrete but calls the virtual self.alloc
def test_calloc_polymorphic(mgr: memhub.MemManager*) -> int:
p: t.CPtr = mgr.calloc(4, 8)
p: rawptr = mgr.calloc(4, 8)
if p is None:
return 0
# Verify zero-fill: the first byte should be 0
first_byte: uint8 = uint8(*uint64(p, t.CPtr))
first_byte: uint8 = uint8(*(uint64*(p)))
if first_byte != 0:
return 0
return 1
@t.CExport
def main() -> int:
export def main() -> int:
testcheck.begin("MemhubTest: polymorphic memory manager")
arena1: bytes = stdlib.malloc(65536)
@@ -38,42 +35,42 @@ def main() -> int:
# ========== MemPool (bump) ==========
testcheck.section("MemPool (bump)")
pool: memhub.MemPool = memhub.MemPool(arena1, 65536)
p1: t.CPtr = pool.alloc(100)
p1: rawptr = pool.alloc(100)
testcheck.check(p1 is not None, "MemPool alloc 100", "FAIL")
p2: t.CPtr = pool.alloc(200)
p2: rawptr = pool.alloc(200)
testcheck.check(p2 is not None, "MemPool alloc 200", "FAIL")
testcheck.check(uint64(p1) != uint64(p2), "MemPool different ptrs", "FAIL")
pool.reset()
p3: t.CPtr = pool.alloc(100)
p3: rawptr = pool.alloc(100)
testcheck.check(p3 is not None, "MemPool alloc after reset", "FAIL")
testcheck.check(uint64(p3) == uint64(p1), "MemPool reset reuses addr", "FAIL")
# ========== MemSlab (fixed block) ==========
testcheck.section("MemSlab (fixed block)")
slab: memhub.MemSlab = memhub.MemSlab(arena2, 65536, 64)
s1: t.CPtr = slab.alloc(32)
s1: rawptr = slab.alloc(32)
testcheck.check(s1 is not None, "MemSlab alloc 32", "FAIL")
s2: t.CPtr = slab.alloc(64)
s2: rawptr = slab.alloc(64)
testcheck.check(s2 is not None, "MemSlab alloc 64", "FAIL")
s3: t.CPtr = slab.alloc(128)
s3: rawptr = slab.alloc(128)
testcheck.check(s3 is None, "MemSlab alloc > block_size fails", "FAIL")
slab.free(s1)
s4: t.CPtr = slab.alloc(32)
s4: rawptr = slab.alloc(32)
testcheck.check(s4 is not None, "MemSlab alloc after free", "FAIL")
testcheck.check(uint64(s4) == uint64(s1), "MemSlab free reuse addr", "FAIL")
# ========== MemBuddy (buddy system) ==========
testcheck.section("MemBuddy (buddy system)")
buddy: memhub.MemBuddy = memhub.MemBuddy(arena3, 65536)
b1: t.CPtr = buddy.alloc(100)
b1: rawptr = buddy.alloc(100)
testcheck.check(b1 is not None, "MemBuddy alloc 100", "FAIL")
b2: t.CPtr = buddy.alloc(200)
b2: rawptr = buddy.alloc(200)
testcheck.check(b2 is not None, "MemBuddy alloc 200", "FAIL")
buddy.free(b1)
b3: t.CPtr = buddy.alloc(100)
b3: rawptr = buddy.alloc(100)
testcheck.check(b3 is not None, "MemBuddy alloc after free", "FAIL")
# Grow via realloc
b4: t.CPtr = buddy.realloc(b2, 400)
b4: rawptr = buddy.realloc(b2, 400)
testcheck.check(b4 is not None, "MemBuddy realloc 200->400", "FAIL")
# ========== Polymorphic dispatch (core test) ==========
+1 -2
View File
@@ -1,9 +1,8 @@
import t, c
import testcheck
import mpooltest
def main() -> int | t.CExport:
export def main() -> int:
testcheck.begin("MpoolOopTest: MemPool OOP 测试")
testcheck.section("MPool OOP")
mpooltest.mpool_main()
+3 -5
View File
@@ -1,12 +1,10 @@
import t, c
from t import CInt, CPtr, CChar
import viperlib
import viperio
import stdlib
import memhub
def mpool_main() -> CInt:
def mpool_main() -> int:
buf: bytes = stdlib.malloc(256)
arena: bytes = stdlib.malloc(4096)
@@ -56,7 +54,7 @@ def mpool_main() -> CInt:
stdlib.free(arena2)
arena3: bytes = stdlib.malloc(4096)
hpool: memhub.MemPool | CPtr = memhub.MemPool(arena3, 4096)
hpool: memhub.MemPool* = memhub.MemPool(arena3, 4096)
h1: bytes = hpool.alloc(32)
h2: bytes = hpool.alloc(64)
if h1 != None and h2 != None:
@@ -78,7 +76,7 @@ def mpool_main() -> CInt:
arena4: bytes = stdlib.malloc(4096)
with memhub.MemPool(arena4, 4096) as bpool:
wb: viperio.Buf | CPtr = bpool.alloc_buf(128)
wb: viperio.Buf* = bpool.alloc_buf(128)
if wb.data != None:
viperlib.snprintf(wb.cstr(), 128, "MPool alloc_buf: hello from Buf!")
print(wb.cstr())
+37 -42
View File
@@ -1,7 +1,5 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CPtr, CChar, CInt32T, CFloat64T, CExport, State
import viperlib
import stdlib
import testcheck
@@ -10,140 +8,137 @@ import testcheck
# === 1. multiple inheritance field merging ===
class A:
a: CInt
a: int
def __init__(self, a: CInt):
def __init__(self, a: int):
self.a = a
def get_a(self) -> CInt:
def get_a(self) -> int:
return self.a
class B:
b: CInt
b: int
def __init__(self, b: CInt):
def __init__(self, b: int):
self.b = b
def get_b(self) -> CInt:
def get_b(self) -> int:
return self.b
# Multiple inheritance C(A, B): fields flatten to layout [a, b, c].
class C(A, B):
c: CInt
c: int
def __init__(self, a: CInt, b: CInt, cc: CInt):
def __init__(self, a: int, b: int, cc: int):
self.a = a
self.b = b
self.c = cc
def get_c(self) -> CInt:
def get_c(self) -> int:
return self.c
# === 2. diamond dedup + leftmost priority ===
class Base:
shared: CInt
shared: int
def who(self) -> CInt:
def who(self) -> int:
return 1
def base_method(self) -> CInt:
def base_method(self) -> int:
return 100
class Left(Base):
def who(self) -> CInt:
def who(self) -> int:
return 2
class Right(Base):
def who(self) -> CInt:
def who(self) -> int:
return 3
# Diamond(Left, Right) shares Base: Base.shared flattens once,
# and who() resolves to Left (leftmost priority).
class Diamond(Left, Right):
def __init__(self, s: CInt):
def __init__(self, s: int):
self.shared = s
# === 3. virtual method multiple-inheritance vtable ===
@t.CVTable
class ShapeM:
def area(self) -> CFloat64T:
virtual class ShapeM:
def area(self) -> double:
return 0.0
@t.CVTable
class ColorM:
color: CInt
virtual class ColorM:
color: int
def __init__(self, color: CInt):
def __init__(self, color: int):
self.color = color
def color_code(self) -> CInt:
def color_code(self) -> int:
return self.color
@t.CVTable
class ColoredCircle(ShapeM, ColorM):
r: CFloat64T
virtual class ColoredCircle(ShapeM, ColorM):
r: double
def __init__(self, r: CFloat64T, color: CInt):
def __init__(self, r: double, color: int):
self.color = color
self.r = r
def area(self) -> CFloat64T:
def area(self) -> double:
return 3.14159265 * self.r * self.r
# === 4. operator overloading + method inheritance chain (MRO) ===
class Vec2M:
x: CFloat64T
y: CFloat64T
x: double
y: double
def __new__() -> 'Vec2M' | CPtr:
def __new__() -> Vec2M*:
return stdlib.malloc(16)
def __init__(self, x: CFloat64T, y: CFloat64T):
def __init__(self, x: double, y: double):
self.x = x
self.y = y
def __add__(self, b: 'Vec2M' | CPtr) -> 'Vec2M' | CPtr:
def __add__(self, b: Vec2M*) -> Vec2M*:
return Vec2M(self.x + b.x, self.y + b.y)
class Vec2Extra:
# Field access uses the defining class's fields (VPC model); does not
# reference Vec2M's x/y (cross-parent field access is out of scope here).
def extra_val(self) -> CInt:
def extra_val(self) -> int:
return 7
# Multiple inheritance: __add__ comes from Vec2M (operator-overload MRO),
# extra_val from Vec2Extra (method lookup MRO).
class Vec2Both(Vec2M, Vec2Extra):
def __new__() -> 'Vec2Both' | CPtr:
def __new__() -> Vec2Both*:
return stdlib.malloc(16)
def __init__(self, x: CFloat64T, y: CFloat64T):
def __init__(self, x: double, y: double):
self.x = x
self.y = y
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
testcheck.begin("MultiInheritTest: 多继承专项测试")
buf: CChar | CPtr = CPtr(stdlib.malloc(256))
buf: str = stdlib.malloc(256)
# === 1. field merge + attribute access + method calls ===
testcheck.section("多继承字段合并")
@@ -171,7 +166,7 @@ def main() -> CInt | CExport:
# === 3. virtual method multiple-inheritance vtable ===
testcheck.section("虚方法多继承 vtable")
cc = ColoredCircle(3.0, 7)
area: CFloat64T = cc.area()
area: double = cc.area()
viperlib.snprintf(buf, 256, "ColoredCircle: r=%.1f color=%d area=%.2f code=%d",
cc.r, cc.color, area, cc.color_code())
print(buf)
@@ -189,7 +184,7 @@ def main() -> CInt | CExport:
print(buf)
testcheck.check(v3.x == 4.0, "Vec2Both __add__ 继承 OK", "Vec2Both __add__ 继承 FAILED")
testcheck.check(v3.y == 6.0, "Vec2Both __add__ y OK", "Vec2Both __add__ y FAILED")
lsq: CInt = v1.extra_val()
lsq: int = v1.extra_val()
viperlib.snprintf(buf, 256, "Vec2Both extra_val: %d", lsq)
print(buf)
testcheck.check(lsq == 7, "extra_val 继承(Vec2Extra) OK", "extra_val 继承(Vec2Extra) FAILED")
@@ -1,5 +1,3 @@
import t, c
def g(x: int) -> int:
return x
-2
View File
@@ -1,5 +1,3 @@
import t, c
def f(a: int, b: int) -> int:
return a + b
-2
View File
@@ -1,5 +1,3 @@
import t, c
def f(a: int, b: int) -> int:
return a + b
@@ -1,5 +1,3 @@
import t, c
def f(a: int, b: int) -> int:
return a + b
@@ -1,4 +1,3 @@
import t, c
import lib.core.Handles.HandlesStruct as HandlesStruct
def main() -> int:
@@ -1,4 +1,3 @@
import t, c
# Stale pre-move path; the import is expected to fail.
import lib.Stub.StubMergerStore as StubMergerStore
@@ -1,4 +1,3 @@
import t, c
import lib.NopeModule as NopeModule
def main() -> int:
-2
View File
@@ -1,4 +1,2 @@
import t, c
def h(x: int) -> int:
x = x + 1
-2
View File
@@ -1,4 +1,2 @@
import t, c
def main() -> int:
return foo(1)
-2
View File
@@ -1,5 +1,3 @@
import t, c
from stdint import *
import stdio
def main() -> int:
+128 -130
View File
@@ -1,5 +1,3 @@
import t, c
from t import CInt, CExport, CPtr
from stdio import printf
import memhub
import stdlib
@@ -15,10 +13,10 @@ from ast import (
)
ARENA_SIZE: CInt = 16777216
ARENA_SIZE: int = 16777216
def main() -> CInt | CExport:
export def main() -> int:
printf("=== NewAstTest Start ===\n")
# Initialize allocator
@@ -26,17 +24,17 @@ def main() -> CInt | CExport:
if arena is None:
printf("FAIL: arena alloc failed\n")
return 1
pool: memhub.MemBuddy | CPtr = memhub.MemBuddy(arena, ARENA_SIZE)
pool: memhub.MemBuddy* = memhub.MemBuddy(arena, ARENA_SIZE)
if pool is None:
printf("FAIL: pool init failed\n")
return 1
passed: CInt = 0
failed: CInt = 0
passed: int = 0
failed: int = 0
# --- Allocate dump buffer for AST round-trip output tests ---
DUMP_BUF_SIZE: sizet = 8192
dump_buf: char | CPtr = stdlib.malloc(DUMP_BUF_SIZE)
dump_buf: char* = stdlib.malloc(DUMP_BUF_SIZE)
if dump_buf is None:
printf("FAIL: dump_buf alloc failed\n")
stdlib.free(arena)
@@ -49,7 +47,7 @@ def main() -> CInt | CExport:
case _:
pass
"""
match_mod: Module | CPtr = parse(match_src, pool)
match_mod: Module* = parse(match_src, pool)
if match_mod is not None and match_mod.kind() == ASTKind.Module:
passed += 1
printf("PASS: parse('match x: case 1: ... case _: ...') -> Module\n")
@@ -58,7 +56,7 @@ def main() -> CInt | CExport:
printf("FAIL: parse match with cases failed\n")
# --- Test 1: Name node creation ---
name_x: Name | CPtr = Name(pool, "x", ASTCtx.Load)
name_x: Name* = Name(pool, "x", ASTCtx.Load)
if name_x is None:
printf("FAIL: Name creation\n")
failed += 1
@@ -67,7 +65,7 @@ def main() -> CInt | CExport:
printf("PASS: Name('x'), kind=%d\n", name_x.kind())
# --- Test 2: ConstantInt node ---
int_42: Constant | CPtr = Constant(pool, CONST_INT, 42, 0.0, None, 1, 0)
int_42: Constant* = Constant(pool, CONST_INT, 42, 0.0, None, 1, 0)
if int_42 is None:
printf("FAIL: ConstantInt creation\n")
failed += 1
@@ -77,7 +75,7 @@ def main() -> CInt | CExport:
int_42.kind(), int_42.int_val)
# --- Test 3: ConstantStr node ---
str_hello: Constant | CPtr = Constant(pool, CONST_STR, 0, 0.0, "hello", 2, 0)
str_hello: Constant* = Constant(pool, CONST_STR, 0, 0.0, "hello", 2, 0)
if str_hello is None:
printf("FAIL: ConstantStr creation\n")
failed += 1
@@ -86,7 +84,7 @@ def main() -> CInt | CExport:
printf("PASS: ConstantStr('hello'), kind=%d\n", str_hello.kind())
# --- Test 4: ConstantNone node ---
const_none: Constant | CPtr = Constant(pool, CONST_NONE, 0, 0.0, None, 3, 0)
const_none: Constant* = Constant(pool, CONST_NONE, 0, 0.0, None, 3, 0)
if const_none is None:
printf("FAIL: ConstantNone creation\n")
failed += 1
@@ -95,7 +93,7 @@ def main() -> CInt | CExport:
printf("PASS: ConstantNone, kind=%d\n", const_none.kind())
# --- Test 5: BinOp node (x + 42) ---
binop: BinOp | CPtr = BinOp(pool, name_x, OpKind.Add, int_42)
binop: BinOp* = BinOp(pool, name_x, OpKind.Add, int_42)
if binop is None:
printf("FAIL: BinOp creation\n")
failed += 1
@@ -104,7 +102,7 @@ def main() -> CInt | CExport:
printf("PASS: BinOp(Add), kind=%d\n", binop.kind())
# --- Test 6: UnaryOp node (-x) ---
unary: UnaryOp | CPtr = UnaryOp(pool, OpKind.USub, name_x)
unary: UnaryOp* = UnaryOp(pool, OpKind.USub, name_x)
if unary is None:
printf("FAIL: UnaryOp creation\n")
failed += 1
@@ -112,8 +110,8 @@ def main() -> CInt | CExport:
passed += 1
printf("PASS: UnaryOp(USub), kind=%d\n", unary.kind())
# --- Test 7: list[AST | CPtr] container ---
body: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8)
# --- Test 7: list[AST*] container ---
body: list[AST*]* = list[AST*](pool, 8)
if body is None:
printf("FAIL: list creation\n")
failed += 1
@@ -130,9 +128,9 @@ def main() -> CInt | CExport:
# --- Test 8: list get + kind dispatch ---
if body is not None:
item0: AST | CPtr = body.get(0)
item0: AST* = body.get(0)
if item0 is not None:
k: CInt = item0.kind()
k: int = item0.kind()
if k == ASTKind.BinOp:
passed += 1
printf("PASS: list get(0).kind()=%d (BinOp)\n", k)
@@ -144,7 +142,7 @@ def main() -> CInt | CExport:
printf("FAIL: list get(0) returned None\n")
# --- Test 9: Module node (Module(pool) + append) ---
mod: Module | CPtr = Module(pool)
mod: Module* = Module(pool)
if mod is None:
printf("FAIL: Module creation\n")
failed += 1
@@ -155,8 +153,8 @@ def main() -> CInt | CExport:
printf("PASS: Module, kind=%d\n", mod.kind())
# --- Test 10: polymorphic dispatch via AST base pointer kind() ---
ast_ptr: AST | CPtr = mod
poly_kind: CInt = ast_ptr.kind()
ast_ptr: AST* = mod
poly_kind: int = ast_ptr.kind()
if poly_kind == ASTKind.Module:
passed += 1
printf("PASS: polymorphic kind()=%d (Module via AST ptr)\n", poly_kind)
@@ -166,9 +164,9 @@ def main() -> CInt | CExport:
# --- Test 11: polymorphic dispatch on list elements ---
if body is not None:
ast_item: AST | CPtr = body.get(1)
ast_item: AST* = body.get(1)
if ast_item is not None:
pk2: CInt = ast_item.kind()
pk2: int = ast_item.kind()
if pk2 == ASTKind.UnaryOp:
passed += 1
printf("PASS: polymorphic kind()=%d (UnaryOp via AST ptr)\n", pk2)
@@ -180,7 +178,7 @@ def main() -> CInt | CExport:
printf("FAIL: list get(1) returned None\n")
# --- Test 12: Return node ---
ret: Return | CPtr = Return(pool, binop)
ret: Return* = Return(pool, binop)
if ret is None:
printf("FAIL: Return creation\n")
failed += 1
@@ -189,7 +187,7 @@ def main() -> CInt | CExport:
printf("PASS: Return, kind=%d\n", ret.kind())
# --- Test 13: Expr statement node ---
expr_stmt: Expr | CPtr = Expr(pool, binop)
expr_stmt: Expr* = Expr(pool, binop)
if expr_stmt is None:
printf("FAIL: Expr creation\n")
failed += 1
@@ -198,8 +196,8 @@ def main() -> CInt | CExport:
printf("PASS: Expr, kind=%d\n", expr_stmt.kind())
# --- Test 14: If node (If(pool, test, orelse), body = children) ---
empty_else: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8)
if_stmt: If | CPtr = If(pool, binop, empty_else)
empty_else: list[AST*]* = list[AST*](pool, 8)
if_stmt: If* = If(pool, binop, empty_else)
if if_stmt is None:
printf("FAIL: If creation\n")
failed += 1
@@ -210,11 +208,11 @@ def main() -> CInt | CExport:
printf("PASS: If, kind=%d\n", if_stmt.kind())
# --- Test 15: Compare node ---
cmp_ops: list[int] | CPtr = list[int](pool)
cmp_ops: list[int]* = list[int](pool)
cmp_ops.append(OpKind.Lt)
cmp_comparators: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8)
cmp_comparators: list[AST*]* = list[AST*](pool, 8)
cmp_comparators.append(int_42)
cmp_node: Compare | CPtr = Compare(pool, name_x, cmp_ops, cmp_comparators)
cmp_node: Compare* = Compare(pool, name_x, cmp_ops, cmp_comparators)
if cmp_node is None:
printf("FAIL: Compare creation\n")
failed += 1
@@ -223,9 +221,9 @@ def main() -> CInt | CExport:
printf("PASS: Compare, kind=%d\n", cmp_node.kind())
# --- Test 16: Assign node ---
assign_targets: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8)
assign_targets: list[AST*]* = list[AST*](pool, 8)
assign_targets.append(name_x)
assign_node: Assign | CPtr = Assign(pool, assign_targets, int_42)
assign_node: Assign* = Assign(pool, assign_targets, int_42)
if assign_node is None:
printf("FAIL: Assign creation\n")
failed += 1
@@ -234,10 +232,10 @@ def main() -> CInt | CExport:
printf("PASS: Assign, kind=%d\n", assign_node.kind())
# --- Test 17: Call node ---
call_args: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8)
call_args: list[AST*]* = list[AST*](pool, 8)
call_args.append(int_42)
call_kwargs: list[AST | CPtr] | CPtr = list[AST | CPtr](pool, 8)
call_node: Call | CPtr = Call(pool, name_x, call_args, call_kwargs)
call_kwargs: list[AST*]* = list[AST*](pool, 8)
call_node: Call* = Call(pool, name_x, call_args, call_kwargs)
if call_node is None:
printf("FAIL: Call creation\n")
failed += 1
@@ -282,11 +280,11 @@ def main() -> CInt | CExport:
# --- Test 21: Module.children polymorphic dispatch ---
if mod is not None and mod.children is not None:
c0: AST | CPtr = mod.children.get(0)
c1: AST | CPtr = mod.children.get(1)
c0: AST* = mod.children.get(0)
c1: AST* = mod.children.get(1)
if c0 is not None and c1 is not None:
k0: CInt = c0.kind()
k1: CInt = c1.kind()
k0: int = c0.kind()
k1: int = c1.kind()
if k0 == ASTKind.BinOp and k1 == ASTKind.UnaryOp:
passed += 1
printf("PASS: Module.children[0]=BinOp, [1]=UnaryOp\n")
@@ -315,7 +313,7 @@ def main() -> CInt | CExport:
# --- Test 23: parent upward traversal (child.parent == if_stmt) ---
if if_stmt is not None and if_stmt.children is not None:
first_child: AST | CPtr = if_stmt.children.get(0)
first_child: AST* = if_stmt.children.get(0)
if first_child is not None and first_child.parent is if_stmt:
passed += 1
printf("PASS: If.children[0].parent == If\n")
@@ -328,7 +326,7 @@ def main() -> CInt | CExport:
# --- Test 24: parse_expression on "x + 42" ---
expr_src: str = "x + 42"
expr_tree: AST | CPtr = parse_expression(expr_src, pool)
expr_tree: AST* = parse_expression(expr_src, pool)
if expr_tree is not None:
passed += 1
printf("PASS: parse_expression('x + 42') -> kind=%d\n", expr_tree.kind())
@@ -338,7 +336,7 @@ def main() -> CInt | CExport:
# --- Test 25: parse simple module "x = 42" ---
mod_src: str = "x = 42\n"
parsed_mod: Module | CPtr = parse(mod_src, pool)
parsed_mod: Module* = parse(mod_src, pool)
if parsed_mod is not None and parsed_mod.kind() == ASTKind.Module:
passed += 1
printf("PASS: parse('x = 42') -> Module, kind=%d\n", parsed_mod.kind())
@@ -361,9 +359,9 @@ def main() -> CInt | CExport:
# --- Test 27: parsed module child kind check (Assign) ---
if parsed_mod is not None and parsed_mod.children is not None:
pmod_child: AST | CPtr = parsed_mod.children.get(0)
pmod_child: AST* = parsed_mod.children.get(0)
if pmod_child is not None:
pmod_k: CInt = pmod_child.kind()
pmod_k: int = pmod_child.kind()
if pmod_k == ASTKind.Assign:
passed += 1
printf("PASS: parsed Module.children[0].kind()=%d (Assign)\n", pmod_k)
@@ -383,7 +381,7 @@ def main() -> CInt | CExport:
b = 2
c = a + b
"""
multi_mod: Module | CPtr = parse(multi_src, pool)
multi_mod: Module* = parse(multi_src, pool)
if multi_mod is not None and multi_mod.children is not None:
multi_cnt: sizet = multi_mod.children.__len__()
if multi_cnt == 3:
@@ -400,10 +398,10 @@ c = a + b
if_src: str = """if x > 0:
y = 1
"""
if_mod: Module | CPtr = parse(if_src, pool)
if_mod: Module* = parse(if_src, pool)
if if_mod is not None and if_mod.children is not None:
if_cnt2: sizet = if_mod.children.__len__()
if_k: CInt = if_mod.children.get(0).kind()
if_k: int = if_mod.children.get(0).kind()
if if_cnt2 == 1 and if_k == ASTKind.If:
passed += 1
printf("PASS: parse if, children=%zu kind=%d (If)\n", if_cnt2, if_k)
@@ -418,10 +416,10 @@ c = a + b
for_src: str = """for i in range(10):
pass
"""
for_mod: Module | CPtr = parse(for_src, pool)
for_mod: Module* = parse(for_src, pool)
if for_mod is not None and for_mod.children is not None:
for_cnt: sizet = for_mod.children.__len__()
for_k: CInt = for_mod.children.get(0).kind()
for_k: int = for_mod.children.get(0).kind()
if for_cnt == 1 and for_k == ASTKind.For:
passed += 1
printf("PASS: parse for, children=%zu kind=%d (For)\n", for_cnt, for_k)
@@ -436,10 +434,10 @@ c = a + b
while_src: str = """while x < 100:
x = x + 1
"""
while_mod: Module | CPtr = parse(while_src, pool)
while_mod: Module* = parse(while_src, pool)
if while_mod is not None and while_mod.children is not None:
while_cnt: sizet = while_mod.children.__len__()
while_k: CInt = while_mod.children.get(0).kind()
while_k: int = while_mod.children.get(0).kind()
if while_cnt == 1 and while_k == ASTKind.While:
passed += 1
printf("PASS: parse while, children=%zu kind=%d (While)\n", while_cnt, while_k)
@@ -454,10 +452,10 @@ c = a + b
def_src: str = """def foo(a, b):
return a + b
"""
def_mod: Module | CPtr = parse(def_src, pool)
def_mod: Module* = parse(def_src, pool)
if def_mod is not None and def_mod.children is not None:
def_cnt: sizet = def_mod.children.__len__()
def_k: CInt = def_mod.children.get(0).kind()
def_k: int = def_mod.children.get(0).kind()
if def_cnt == 1 and def_k == ASTKind.FunctionDef:
passed += 1
printf("PASS: parse def, children=%zu kind=%d (FunctionDef)\n", def_cnt, def_k)
@@ -470,9 +468,9 @@ c = a + b
# --- Test 33: parse complex expression (a + b * c - 1) ---
complex_expr_src: str = "a + b * c - 1"
complex_expr: AST | CPtr = parse_expression(complex_expr_src, pool)
complex_expr: AST* = parse_expression(complex_expr_src, pool)
if complex_expr is not None:
ce_k: CInt = complex_expr.kind()
ce_k: int = complex_expr.kind()
if ce_k == ASTKind.Expression:
passed += 1
printf("PASS: parse complex expr, kind=%d (Expression)\n", ce_k)
@@ -488,10 +486,10 @@ c = a + b
if i > 5:
x = 1
"""
nested_mod: Module | CPtr = parse(nested_src, pool)
nested_mod: Module* = parse(nested_src, pool)
if nested_mod is not None and nested_mod.children is not None:
nested_cnt: sizet = nested_mod.children.__len__()
nested_k: CInt = nested_mod.children.get(0).kind()
nested_k: int = nested_mod.children.get(0).kind()
if nested_cnt == 1 and nested_k == ASTKind.For:
passed += 1
printf("PASS: parse nested for-if, children=%zu kind=%d (For)\n", nested_cnt, nested_k)
@@ -511,7 +509,7 @@ else:
z = 0
w = z * 2
"""
mixed_mod: Module | CPtr = parse(mixed_src, pool)
mixed_mod: Module* = parse(mixed_src, pool)
if mixed_mod is not None and mixed_mod.children is not None:
mixed_cnt: sizet = mixed_mod.children.__len__()
if mixed_cnt == 4:
@@ -616,7 +614,7 @@ w = z * 2
# --- Test 42: type_name polymorphic dispatch check ---
if parsed_mod is not None and parsed_mod.children is not None:
tn_node: AST | CPtr = parsed_mod.children.get(0)
tn_node: AST* = parsed_mod.children.get(0)
if tn_node is not None:
tn: str = tn_node.type_name()
if tn is not None and string.strcmp(tn, "Assign") == 0:
@@ -638,10 +636,10 @@ w = z * 2
def bar(self):
return self.x
"""
class_mod: Module | CPtr = parse(class_src, pool)
class_mod: Module* = parse(class_src, pool)
if class_mod is not None and class_mod.children is not None:
class_cnt: sizet = class_mod.children.__len__()
class_k: CInt = class_mod.children.get(0).kind()
class_k: int = class_mod.children.get(0).kind()
if class_cnt == 1 and class_k == ASTKind.ClassDef:
passed += 1
printf("PASS: parse class, children=%zu kind=%d (ClassDef)\n", class_cnt, class_k)
@@ -658,10 +656,10 @@ w = z * 2
except:
x = 0
"""
try_mod: Module | CPtr = parse(try_src, pool)
try_mod: Module* = parse(try_src, pool)
if try_mod is not None and try_mod.children is not None:
try_cnt: sizet = try_mod.children.__len__()
try_k: CInt = try_mod.children.get(0).kind()
try_k: int = try_mod.children.get(0).kind()
if try_cnt == 1 and try_k == ASTKind.Try:
passed += 1
printf("PASS: parse try/except, children=%zu kind=%d (Try)\n", try_cnt, try_k)
@@ -676,11 +674,11 @@ except:
import_src: str = """import os
from sys import path
"""
import_mod: Module | CPtr = parse(import_src, pool)
import_mod: Module* = parse(import_src, pool)
if import_mod is not None and import_mod.children is not None:
import_cnt: sizet = import_mod.children.__len__()
k0: CInt = import_mod.children.get(0).kind()
k1: CInt = import_mod.children.get(1).kind()
k0: int = import_mod.children.get(0).kind()
k1: int = import_mod.children.get(1).kind()
if import_cnt == 2 and k0 == ASTKind.Import and k1 == ASTKind.ImportFrom:
passed += 1
printf("PASS: parse import, children=%zu k0=%d(Import) k1=%d(ImportFrom)\n",
@@ -696,10 +694,10 @@ from sys import path
aug_src: str = """x = 0
x += 1
"""
aug_mod: Module | CPtr = parse(aug_src, pool)
aug_mod: Module* = parse(aug_src, pool)
if aug_mod is not None and aug_mod.children is not None:
aug_cnt: sizet = aug_mod.children.__len__()
aug_k: CInt = aug_mod.children.get(1).kind()
aug_k: int = aug_mod.children.get(1).kind()
if aug_cnt == 2 and aug_k == ASTKind.AugAssign:
passed += 1
printf("PASS: parse AugAssign, children=%zu kind=%d (AugAssign)\n", aug_cnt, aug_k)
@@ -712,10 +710,10 @@ x += 1
# --- Test 47: parse conditional expression (x if y else z) ---
ifexp_src: str = "x if y else z"
ifexp_tree: AST | CPtr = parse_expression(ifexp_src, pool)
ifexp_expr: Expression | CPtr = (Expression | CPtr)(ifexp_tree)
ifexp_tree: AST* = parse_expression(ifexp_src, pool)
ifexp_expr: Expression* = (Expression*)(ifexp_tree)
if ifexp_expr is not None and ifexp_expr.body is not None:
ie_k: CInt = ifexp_expr.body.kind()
ie_k: int = ifexp_expr.body.kind()
if ie_k == ASTKind.IfExp:
passed += 1
printf("PASS: parse IfExp, kind=%d (IfExp)\n", ie_k)
@@ -733,10 +731,10 @@ x += 1
return x
return inner()
"""
nested_def_mod: Module | CPtr = parse(nested_def_src, pool)
nested_def_mod: Module* = parse(nested_def_src, pool)
if nested_def_mod is not None and nested_def_mod.children is not None:
nd_cnt: sizet = nested_def_mod.children.__len__()
nd_k: CInt = nested_def_mod.children.get(0).kind()
nd_k: int = nested_def_mod.children.get(0).kind()
if nd_cnt == 1 and nd_k == ASTKind.FunctionDef:
passed += 1
printf("PASS: parse nested def, children=%zu kind=%d (FunctionDef)\n", nd_cnt, nd_k)
@@ -757,7 +755,7 @@ except:
def bar():
return y
"""
complex_mod: Module | CPtr = parse(complex_src, pool)
complex_mod: Module* = parse(complex_src, pool)
if complex_mod is not None:
dump(complex_mod, dump_buf, DUMP_BUF_SIZE)
printf("--- AST dump of complex module ---\n%s\n--- end dump ---\n", dump_buf)
@@ -789,7 +787,7 @@ elif x == 1:
else:
y = 0
"""
cmix_mod: Module | CPtr = parse(complex_mixed_src, pool)
cmix_mod: Module* = parse(complex_mixed_src, pool)
if cmix_mod is not None and cmix_mod.children is not None:
cmix_cnt: sizet = cmix_mod.children.__len__()
dump(cmix_mod, dump_buf, DUMP_BUF_SIZE)
@@ -821,7 +819,7 @@ else:
# --- Test 51: Lambda expression ---
lambda_src: str = "f = lambda x: x + 1"
lambda_mod: Module | CPtr = parse(lambda_src, pool)
lambda_mod: Module* = parse(lambda_src, pool)
if lambda_mod is not None:
dump(lambda_mod, dump_buf, DUMP_BUF_SIZE)
has_lambda: str = string.strstr(dump_buf, "Lambda(")
@@ -839,7 +837,7 @@ else:
# --- Test 52: List comprehension ---
listcomp_src: str = "squares = [x*x for x in range(10)]"
lc_mod: Module | CPtr = parse(listcomp_src, pool)
lc_mod: Module* = parse(listcomp_src, pool)
if lc_mod is not None:
dump(lc_mod, dump_buf, DUMP_BUF_SIZE)
has_lc: str = string.strstr(dump_buf, "ListComp(")
@@ -857,7 +855,7 @@ else:
# --- Test 53: Dict comprehension ---
dictcomp_src: str = "d = {k: v for k, v in items}"
dc_mod: Module | CPtr = parse(dictcomp_src, pool)
dc_mod: Module* = parse(dictcomp_src, pool)
if dc_mod is not None:
dump(dc_mod, dump_buf, DUMP_BUF_SIZE)
has_dc: str = string.strstr(dump_buf, "DictComp(")
@@ -873,7 +871,7 @@ else:
# --- Test 54: Set comprehension ---
setcomp_src: str = "s = {x for x in items}"
sc_mod: Module | CPtr = parse(setcomp_src, pool)
sc_mod: Module* = parse(setcomp_src, pool)
if sc_mod is not None:
dump(sc_mod, dump_buf, DUMP_BUF_SIZE)
has_sc: str = string.strstr(dump_buf, "SetComp(")
@@ -891,7 +889,7 @@ else:
with_src: str = """with open('f') as f:
data = f.read()
"""
with_mod: Module | CPtr = parse(with_src, pool)
with_mod: Module* = parse(with_src, pool)
if with_mod is not None and with_mod.children is not None:
dump(with_mod, dump_buf, DUMP_BUF_SIZE)
has_with: str = string.strstr(dump_buf, "With(")
@@ -909,7 +907,7 @@ else:
# --- Test 56: Raise statement ---
raise_src: str = "raise ValueError('bad')"
raise_mod: Module | CPtr = parse(raise_src, pool)
raise_mod: Module* = parse(raise_src, pool)
if raise_mod is not None:
dump(raise_mod, dump_buf, DUMP_BUF_SIZE)
has_raise: str = string.strstr(dump_buf, "Raise(")
@@ -925,7 +923,7 @@ else:
# --- Test 57: Assert statement ---
assert_src: str = "assert x > 0, 'x must be positive'"
assert_mod: Module | CPtr = parse(assert_src, pool)
assert_mod: Module* = parse(assert_src, pool)
if assert_mod is not None:
dump(assert_mod, dump_buf, DUMP_BUF_SIZE)
has_assert: str = string.strstr(dump_buf, "Assert(")
@@ -941,7 +939,7 @@ else:
# --- Test 58: Del statement ---
del_src: str = "del x"
del_mod: Module | CPtr = parse(del_src, pool)
del_mod: Module* = parse(del_src, pool)
if del_mod is not None:
dump(del_mod, dump_buf, DUMP_BUF_SIZE)
has_del: str = string.strstr(dump_buf, "Delete(")
@@ -957,7 +955,7 @@ else:
# --- Test 59: Subscript + Slice ---
slice_src: str = "y = a[1:3]"
slice_mod: Module | CPtr = parse(slice_src, pool)
slice_mod: Module* = parse(slice_src, pool)
if slice_mod is not None:
dump(slice_mod, dump_buf, DUMP_BUF_SIZE)
has_sub: str = string.strstr(dump_buf, "Subscript(")
@@ -975,7 +973,7 @@ else:
# --- Test 60: Tuple unpacking ---
tuple_src: str = "a, b = 1, 2"
tuple_mod: Module | CPtr = parse(tuple_src, pool)
tuple_mod: Module* = parse(tuple_src, pool)
if tuple_mod is not None:
dump(tuple_mod, dump_buf, DUMP_BUF_SIZE)
has_tuple: str = string.strstr(dump_buf, "Tuple(")
@@ -991,7 +989,7 @@ else:
# --- Test 61: default args + keyword args signature ---
defdef_src: str = "def f(a, b=10): return a + b"
defdef_mod: Module | CPtr = parse(defdef_src, pool)
defdef_mod: Module* = parse(defdef_src, pool)
if defdef_mod is not None:
dump(defdef_mod, dump_buf, DUMP_BUF_SIZE)
has_fdef: str = string.strstr(dump_buf, "FunctionDef(name='f'")
@@ -1012,7 +1010,7 @@ else:
def f():
pass
"""
deco_mod: Module | CPtr = parse(deco_src, pool)
deco_mod: Module* = parse(deco_src, pool)
if deco_mod is not None:
dump(deco_mod, dump_buf, DUMP_BUF_SIZE)
has_dec: str = string.strstr(dump_buf, "decorator_list=[Name(id='my_dec'")
@@ -1028,7 +1026,7 @@ def f():
# --- Test 63: chained assignment ---
chain_src: str = "a = b = c = 42"
chain_mod: Module | CPtr = parse(chain_src, pool)
chain_mod: Module* = parse(chain_src, pool)
if chain_mod is not None:
dump(chain_mod, dump_buf, DUMP_BUF_SIZE)
has_chain: str = string.strstr(dump_buf, "Assign(targets=[Name(id='a'")
@@ -1047,7 +1045,7 @@ def f():
# --- Test 64: bitwise ops ---
bit_src: str = "y = (a | b) & c ^ d << 2"
bit_mod: Module | CPtr = parse(bit_src, pool)
bit_mod: Module* = parse(bit_src, pool)
if bit_mod is not None:
dump(bit_mod, dump_buf, DUMP_BUF_SIZE)
has_bor: str = string.strstr(dump_buf, "op=BitOr")
@@ -1070,7 +1068,7 @@ def f():
class C(Base1, Base2):
pass
"""
multi_mod: Module | CPtr = parse(multi_src, pool)
multi_mod: Module* = parse(multi_src, pool)
if multi_mod is not None:
dump(multi_mod, dump_buf, DUMP_BUF_SIZE)
m_dec1: str = string.strstr(dump_buf, "Name(id='dec1'")
@@ -1094,7 +1092,7 @@ class C(Base1, Base2):
global x
x = 1
"""
glob_mod: Module | CPtr = parse(glob_src, pool)
glob_mod: Module* = parse(glob_src, pool)
if glob_mod is not None:
dump(glob_mod, dump_buf, DUMP_BUF_SIZE)
has_glob: str = string.strstr(dump_buf, "Global(")
@@ -1110,7 +1108,7 @@ class C(Base1, Base2):
# --- Test 67: f-string (FormattedValue) ---
fstr_src: str = "s = f'value={x}'"
fstr_mod: Module | CPtr = parse(fstr_src, pool)
fstr_mod: Module* = parse(fstr_src, pool)
if fstr_mod is not None:
dump(fstr_mod, dump_buf, DUMP_BUF_SIZE)
has_fv: str = string.strstr(dump_buf, "FormattedValue(")
@@ -1133,7 +1131,7 @@ class C(Base1, Base2):
return x + 1
return inner()
"""
nested_mod: Module | CPtr = parse(nested_src, pool)
nested_mod: Module* = parse(nested_src, pool)
if nested_mod is not None and nested_mod.children is not None:
dump(nested_mod, dump_buf, DUMP_BUF_SIZE)
n_outer: str = string.strstr(dump_buf, "FunctionDef(name='outer'")
@@ -1154,7 +1152,7 @@ class C(Base1, Base2):
case 1:
pass
"""
m_lit_mod: Module | CPtr = parse(m_lit_src, pool)
m_lit_mod: Module* = parse(m_lit_src, pool)
if m_lit_mod is not None:
dump(m_lit_mod, dump_buf, DUMP_BUF_SIZE)
has_mv: str = string.strstr(dump_buf, "MatchValue(")
@@ -1173,7 +1171,7 @@ class C(Base1, Base2):
case "hello":
pass
"""
m_str_mod: Module | CPtr = parse(m_str_src, pool)
m_str_mod: Module* = parse(m_str_src, pool)
if m_str_mod is not None:
dump(m_str_mod, dump_buf, DUMP_BUF_SIZE)
has_mv2: str = string.strstr(dump_buf, "MatchValue(")
@@ -1192,7 +1190,7 @@ class C(Base1, Base2):
case -1:
pass
"""
m_neg_mod: Module | CPtr = parse(m_neg_src, pool)
m_neg_mod: Module* = parse(m_neg_src, pool)
if m_neg_mod is not None:
dump(m_neg_mod, dump_buf, DUMP_BUF_SIZE)
has_mv3: str = string.strstr(dump_buf, "MatchValue(")
@@ -1211,7 +1209,7 @@ class C(Base1, Base2):
case None:
pass
"""
m_none_mod: Module | CPtr = parse(m_none_src, pool)
m_none_mod: Module* = parse(m_none_src, pool)
if m_none_mod is not None:
dump(m_none_mod, dump_buf, DUMP_BUF_SIZE)
has_ms: str = string.strstr(dump_buf, "MatchSingleton(")
@@ -1230,7 +1228,7 @@ class C(Base1, Base2):
case True:
pass
"""
m_true_mod: Module | CPtr = parse(m_true_src, pool)
m_true_mod: Module* = parse(m_true_src, pool)
if m_true_mod is not None:
dump(m_true_mod, dump_buf, DUMP_BUF_SIZE)
has_ms2: str = string.strstr(dump_buf, "MatchSingleton(")
@@ -1249,7 +1247,7 @@ class C(Base1, Base2):
case False:
pass
"""
m_false_mod: Module | CPtr = parse(m_false_src, pool)
m_false_mod: Module* = parse(m_false_src, pool)
if m_false_mod is not None:
dump(m_false_mod, dump_buf, DUMP_BUF_SIZE)
has_ms3: str = string.strstr(dump_buf, "MatchSingleton(")
@@ -1268,7 +1266,7 @@ class C(Base1, Base2):
case _:
pass
"""
m_wild_mod: Module | CPtr = parse(m_wild_src, pool)
m_wild_mod: Module* = parse(m_wild_src, pool)
if m_wild_mod is not None:
dump(m_wild_mod, dump_buf, DUMP_BUF_SIZE)
has_ma: str = string.strstr(dump_buf, "MatchAs(")
@@ -1287,7 +1285,7 @@ class C(Base1, Base2):
case y:
pass
"""
m_cap_mod: Module | CPtr = parse(m_cap_src, pool)
m_cap_mod: Module* = parse(m_cap_src, pool)
if m_cap_mod is not None:
dump(m_cap_mod, dump_buf, DUMP_BUF_SIZE)
has_ma2: str = string.strstr(dump_buf, "name='y'")
@@ -1306,7 +1304,7 @@ class C(Base1, Base2):
case Color.RED:
pass
"""
m_val_mod: Module | CPtr = parse(m_val_src, pool)
m_val_mod: Module* = parse(m_val_src, pool)
if m_val_mod is not None:
dump(m_val_mod, dump_buf, DUMP_BUF_SIZE)
has_mv4: str = string.strstr(dump_buf, "MatchValue(")
@@ -1327,7 +1325,7 @@ class C(Base1, Base2):
case [1, 2]:
pass
"""
m_seq_mod: Module | CPtr = parse(m_seq_src, pool)
m_seq_mod: Module* = parse(m_seq_src, pool)
if m_seq_mod is not None:
dump(m_seq_mod, dump_buf, DUMP_BUF_SIZE)
has_msq: str = string.strstr(dump_buf, "MatchSequence(")
@@ -1346,7 +1344,7 @@ class C(Base1, Base2):
case [a, *rest]:
pass
"""
m_star_mod: Module | CPtr = parse(m_star_src, pool)
m_star_mod: Module* = parse(m_star_src, pool)
if m_star_mod is not None:
dump(m_star_mod, dump_buf, DUMP_BUF_SIZE)
has_mstar: str = string.strstr(dump_buf, "MatchStar(name='rest')")
@@ -1365,7 +1363,7 @@ class C(Base1, Base2):
case Point(x, y):
pass
"""
m_cls_mod: Module | CPtr = parse(m_cls_src, pool)
m_cls_mod: Module* = parse(m_cls_src, pool)
if m_cls_mod is not None:
dump(m_cls_mod, dump_buf, DUMP_BUF_SIZE)
has_mc: str = string.strstr(dump_buf, "MatchClass(")
@@ -1384,7 +1382,7 @@ class C(Base1, Base2):
case Point(x=0, y=0):
pass
"""
m_kwcls_mod: Module | CPtr = parse(m_kwcls_src, pool)
m_kwcls_mod: Module* = parse(m_kwcls_src, pool)
if m_kwcls_mod is not None:
dump(m_kwcls_mod, dump_buf, DUMP_BUF_SIZE)
has_mc2: str = string.strstr(dump_buf, "MatchClass(")
@@ -1403,7 +1401,7 @@ class C(Base1, Base2):
case 1 | 2:
pass
"""
m_or_mod: Module | CPtr = parse(m_or_src, pool)
m_or_mod: Module* = parse(m_or_src, pool)
if m_or_mod is not None:
dump(m_or_mod, dump_buf, DUMP_BUF_SIZE)
has_mo: str = string.strstr(dump_buf, "MatchOr(")
@@ -1422,7 +1420,7 @@ class C(Base1, Base2):
case [x] as p:
pass
"""
m_as_mod: Module | CPtr = parse(m_as_src, pool)
m_as_mod: Module* = parse(m_as_src, pool)
if m_as_mod is not None:
dump(m_as_mod, dump_buf, DUMP_BUF_SIZE)
has_mas: str = string.strstr(dump_buf, "MatchAs(pattern=")
@@ -1443,7 +1441,7 @@ class C(Base1, Base2):
case x if x > 0:
pass
"""
m_guard_mod: Module | CPtr = parse(m_guard_src, pool)
m_guard_mod: Module* = parse(m_guard_src, pool)
if m_guard_mod is not None:
dump(m_guard_mod, dump_buf, DUMP_BUF_SIZE)
has_guard: str = string.strstr(dump_buf, "guard=Compare(")
@@ -1462,7 +1460,7 @@ class C(Base1, Base2):
case {"k": v}:
pass
"""
m_map_mod: Module | CPtr = parse(m_map_src, pool)
m_map_mod: Module* = parse(m_map_src, pool)
if m_map_mod is not None:
dump(m_map_mod, dump_buf, DUMP_BUF_SIZE)
has_mm: str = string.strstr(dump_buf, "MatchMapping(")
@@ -1481,7 +1479,7 @@ class C(Base1, Base2):
case {"k": v, **rest}:
pass
"""
m_map2_mod: Module | CPtr = parse(m_map2_src, pool)
m_map2_mod: Module* = parse(m_map2_src, pool)
if m_map2_mod is not None:
dump(m_map2_mod, dump_buf, DUMP_BUF_SIZE)
has_mm2: str = string.strstr(dump_buf, "MatchMapping(")
@@ -1502,7 +1500,7 @@ class C(Base1, Base2):
case (1 | 2) as p:
pass
"""
m_combo_mod: Module | CPtr = parse(m_combo_src, pool)
m_combo_mod: Module* = parse(m_combo_src, pool)
if m_combo_mod is not None:
dump(m_combo_mod, dump_buf, DUMP_BUF_SIZE)
has_combo_or: str = string.strstr(dump_buf, "MatchOr(")
@@ -1522,13 +1520,13 @@ class C(Base1, Base2):
adef_src: str = """async def f():
pass
"""
adef_mod: Module | CPtr = parse(adef_src, pool)
adef_mod: Module* = parse(adef_src, pool)
if adef_mod is not None and adef_mod.children is not None:
adef_cnt: sizet = adef_mod.children.__len__()
if adef_cnt == 1:
adef_child: AST | CPtr = adef_mod.children.get(0)
adef_child: AST* = adef_mod.children.get(0)
if adef_child is not None and adef_child.kind() == ASTKind.FunctionDef:
adef_fd: FunctionDef | CPtr = (FunctionDef | CPtr)(adef_child)
adef_fd: FunctionDef* = (FunctionDef*)(adef_child)
if (adef_fd.flags & FLAG_IS_ASYNC) != 0:
passed += 1
printf("PASS: async def f() -> FunctionDef with FLAG_IS_ASYNC\n")
@@ -1551,18 +1549,18 @@ class C(Base1, Base2):
async for x in y:
pass
"""
afor_mod: Module | CPtr = parse(afor_src, pool)
afor_mod: Module* = parse(afor_src, pool)
if afor_mod is not None and afor_mod.children is not None:
afor_cnt: sizet = afor_mod.children.__len__()
if afor_cnt == 1:
afor_child: AST | CPtr = afor_mod.children.get(0)
afor_child: AST* = afor_mod.children.get(0)
if afor_child is not None and afor_child.kind() == ASTKind.FunctionDef:
afor_fd2: FunctionDef | CPtr = (FunctionDef | CPtr)(afor_child)
afor_fd2: FunctionDef* = (FunctionDef*)(afor_child)
if (afor_fd2.flags & FLAG_IS_ASYNC) != 0:
if afor_fd2.children is not None:
afor_inner: AST | CPtr = afor_fd2.children.get(0)
afor_inner: AST* = afor_fd2.children.get(0)
if afor_inner is not None and afor_inner.kind() == ASTKind.For:
afor_for: For | CPtr = (For | CPtr)(afor_inner)
afor_for: For* = (For*)(afor_inner)
if (afor_for.flags & FLAG_IS_ASYNC) != 0:
passed += 1
printf("PASS: async for -> For with FLAG_IS_ASYNC\n")
@@ -1595,18 +1593,18 @@ class C(Base1, Base2):
async with ctx:
pass
"""
awith_mod: Module | CPtr = parse(awith_src, pool)
awith_mod: Module* = parse(awith_src, pool)
if awith_mod is not None and awith_mod.children is not None:
awith_cnt: sizet = awith_mod.children.__len__()
if awith_cnt == 1:
awith_child: AST | CPtr = awith_mod.children.get(0)
awith_child: AST* = awith_mod.children.get(0)
if awith_child is not None and awith_child.kind() == ASTKind.FunctionDef:
awith_fd: FunctionDef | CPtr = (FunctionDef | CPtr)(awith_child)
awith_fd: FunctionDef* = (FunctionDef*)(awith_child)
if (awith_fd.flags & FLAG_IS_ASYNC) != 0:
if awith_fd.children is not None:
awith_inner: AST | CPtr = awith_fd.children.get(0)
awith_inner: AST* = awith_fd.children.get(0)
if awith_inner is not None and awith_inner.kind() == ASTKind.With:
awith_w: With | CPtr = (With | CPtr)(awith_inner)
awith_w: With* = (With*)(awith_inner)
if (awith_w.flags & FLAG_IS_ASYNC) != 0:
passed += 1
printf("PASS: async with -> With with FLAG_IS_ASYNC\n")
@@ -1645,7 +1643,7 @@ class C(Base1, Base2):
case _:
pass
"""
m_complex_mod: Module | CPtr = parse(m_complex_src, pool)
m_complex_mod: Module* = parse(m_complex_src, pool)
if m_complex_mod is not None:
dump(m_complex_mod, dump_buf, DUMP_BUF_SIZE)
has_c_mv: str = string.strstr(dump_buf, "MatchValue(")
@@ -1671,13 +1669,13 @@ class C(Base1, Base2):
async for x in y:
pass
"""
acombo_mod: Module | CPtr = parse(acombo_src, pool)
acombo_mod: Module* = parse(acombo_src, pool)
if acombo_mod is not None and acombo_mod.children is not None:
acombo_cnt: sizet = acombo_mod.children.__len__()
if acombo_cnt == 1:
acombo_child: AST | CPtr = acombo_mod.children.get(0)
acombo_child: AST* = acombo_mod.children.get(0)
if acombo_child is not None and acombo_child.kind() == ASTKind.FunctionDef:
acombo_fd2: FunctionDef | CPtr = (FunctionDef | CPtr)(acombo_child)
acombo_fd2: FunctionDef* = (FunctionDef*)(acombo_child)
if (acombo_fd2.flags & FLAG_IS_ASYNC) != 0:
passed += 1
printf("PASS: async def + async with + async for combo\n")
+3 -3
View File
@@ -1,5 +1,5 @@
from stdint import *
import w32.win32console
import win32.win32console
import stdlib
@@ -18,8 +18,8 @@ novirtual class Point:
export def main() -> int:
w32.win32console.SetConsoleCP(65001)
w32.win32console.SetConsoleOutputCP(65001)
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
p: Point* = new heap slife Point(1, 2)
stdlib.free(p) # ← 必须被拒:slife 由编译器在函数出口释放
+3 -3
View File
@@ -1,5 +1,5 @@
from stdint import *
import w32.win32console
import win32.win32console
import stdio
@@ -225,8 +225,8 @@ def Check(name: str, rc: int, fails: int) -> int:
export def main() -> int:
w32.win32console.SetConsoleCP(65001)
w32.win32console.SetConsoleOutputCP(65001)
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
fails: int = 0
fails = Check("CaseBasic", CaseBasic(), fails)
+3 -3
View File
@@ -1,5 +1,5 @@
from stdint import *
import w32.win32console
import win32.win32console
import stdio
import stdlib
import memhub
@@ -30,8 +30,8 @@ class Box[T]:
export def main() -> int:
w32.win32console.SetConsoleCP(65001)
w32.win32console.SetConsoleOutputCP(65001)
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
# (1) stack:等价既有写法 &Point(1, 2),生命期随帧
p1: Point* = new stack slife Point(1, 2)
-2
View File
@@ -1,5 +1,3 @@
import t
import stdio
import string
import testcheck
-2
View File
@@ -1,5 +1,3 @@
import t
import stdio
import string
import testcheck
import linkedlist
+1 -2
View File
@@ -1,9 +1,8 @@
import t, c
import testcheck
import test_numpy
def main() -> int | t.CExport:
export def main() -> int:
testcheck.begin("NumpyTest: numpy 正确性测试")
testcheck.section("numpy Correctness Tests")
test_numpy.test_numpy_correct()
-3
View File
@@ -2,11 +2,8 @@ from stdint import *
import numpy
from stdio import printf
from stdlib import calloc, free
import string
import math
import memhub
import win32.win32base
import t, c
# ============================================================
# Constants
+101 -111
View File
@@ -1,7 +1,5 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CPtr, CChar, CInt32T, CUInt64T, CFloat64T, CExport, State
import viperlib
import stdlib
import testcheck
@@ -9,56 +7,53 @@ import testcheck
# === OOP inheritance + virtual methods ===
@t.CVTable
class Shape:
x: CFloat64T
y: CFloat64T
virtual class Shape:
x: double
y: double
def __init__(self, x: CFloat64T, y: CFloat64T):
def __init__(self, x: double, y: double):
self.x = x
self.y = y
def area(self) -> CFloat64T:
def area(self) -> double:
return 0.0
def perimeter(self) -> CFloat64T:
def perimeter(self) -> double:
return 0.0
def describe(self) -> CFloat64T:
def describe(self) -> double:
return self.area() + self.perimeter()
@t.CVTable
class Circle(Shape):
r: CFloat64T
virtual class Circle(Shape):
r: double
def __init__(self, x: CFloat64T, y: CFloat64T, r: CFloat64T):
def __init__(self, x: double, y: double, r: double):
self.x = x
self.y = y
self.r = r
def area(self) -> CFloat64T:
def area(self) -> double:
return 3.14159265 * self.r * self.r
def perimeter(self) -> CFloat64T:
def perimeter(self) -> double:
return 2.0 * 3.14159265 * self.r
def scale(self, factor: CFloat64T) -> 'Circle' | CPtr:
def scale(self, factor: double) -> 'Circle' | CPtr:
self.r = self.r * factor
return self
def move(self, dx: CFloat64T, dy: CFloat64T) -> 'Circle' | CPtr:
def move(self, dx: double, dy: double) -> 'Circle' | CPtr:
self.x = self.x + dx
self.y = self.y + dy
return self
@t.CVTable
class Rect(Shape):
w: CFloat64T
h: CFloat64T
virtual class Rect(Shape):
w: double
h: double
def __init__(self, x: CFloat64T, y: CFloat64T, w: CFloat64T, h: CFloat64T):
def __init__(self, x: double, y: double, w: double, h: double):
self.x = x
self.y = y
self.w = w
self.h = h
def area(self) -> CFloat64T:
def area(self) -> double:
return self.w * self.h
def perimeter(self) -> CFloat64T:
def perimeter(self) -> double:
return 2.0 * (self.w + self.h)
def scale(self, factor: CFloat64T) -> 'Rect' | CPtr:
def scale(self, factor: double) -> Rect*:
self.w = self.w * factor
self.h = self.h * factor
return self
@@ -67,114 +62,112 @@ class Rect(Shape):
# === operator overloading + chained calls (heap allocated) ===
class Vec2:
x: CFloat64T
y: CFloat64T
x: double
y: double
def __new__() -> 'Vec2' | CPtr:
def __new__() -> Vec2*:
return stdlib.malloc(16)
def __init__(self, x: CFloat64T, y: CFloat64T):
def __init__(self, x: double, y: double):
self.x = x
self.y = y
def __add__(self, b: 'Vec2' | CPtr) -> 'Vec2' | CPtr:
def __add__(self, b: Vec2*) -> Vec2*:
return Vec2(self.x + b.x, self.y + b.y)
def __sub__(self, b: 'Vec2' | CPtr) -> 'Vec2' | CPtr:
def __sub__(self, b: Vec2*) -> Vec2*:
return Vec2(self.x - b.x, self.y - b.y)
def __mul__(self, s: CFloat64T) -> 'Vec2' | CPtr:
def __mul__(self, s: double) -> Vec2*:
return Vec2(self.x * s, self.y * s)
def __neg__(self) -> 'Vec2' | CPtr:
def __neg__(self) -> Vec2*:
return Vec2(-self.x, -self.y)
def dot(self, b: 'Vec2' | CPtr) -> CFloat64T:
def dot(self, b: Vec2*) -> double:
return self.x * b.x + self.y * b.y
def len_sq(self) -> CFloat64T:
def len_sq(self) -> double:
return self.x * self.x + self.y * self.y
class Vec3:
x: CFloat64T
y: CFloat64T
z: CFloat64T
x: double
y: double
z: double
def __new__() -> 'Vec3' | CPtr:
def __new__() -> Vec3*:
return stdlib.malloc(24)
def __init__(self, x: CFloat64T, y: CFloat64T, z: CFloat64T):
def __init__(self, x: double, y: double, z: double):
self.x = x
self.y = y
self.z = z
def __add__(self, b: 'Vec3' | CPtr) -> 'Vec3' | CPtr:
def __add__(self, b: Vec3*) -> Vec3*:
return Vec3(self.x + b.x, self.y + b.y, self.z + b.z)
def __sub__(self, b: 'Vec3' | CPtr) -> 'Vec3' | CPtr:
def __sub__(self, b: Vec3*) -> Vec3*:
return Vec3(self.x - b.x, self.y - b.y, self.z - b.z)
def __mul__(self, s: CFloat64T) -> 'Vec3' | CPtr:
def __mul__(self, s: double) -> Vec3*:
return Vec3(self.x * s, self.y * s, self.z * s)
def __neg__(self) -> 'Vec3' | CPtr:
def __neg__(self) -> Vec3*:
return Vec3(-self.x, -self.y, -self.z)
def dot(self, b: 'Vec3' | CPtr) -> CFloat64T:
def dot(self, b: Vec3*) -> double:
return self.x * b.x + self.y * b.y + self.z * b.z
def cross(self, b: 'Vec3' | CPtr) -> 'Vec3' | CPtr:
def cross(self, b: Vec3*) -> Vec3*:
return Vec3(self.y * b.z - self.z * b.y,
self.z * b.x - self.x * b.z,
self.x * b.y - self.y * b.x)
def len_sq(self) -> CFloat64T:
def len_sq(self) -> double:
return self.dot(self)
# === standalone classes (no inheritance) ===
@t.CVTable
class Dog:
name_val: CInt
health: CInt32T
bark_power: CInt32T
virtual class Dog:
name_val: int
health: int32
bark_power: int32
def __init__(self, name_val: CInt, bark_power: CInt32T):
def __init__(self, name_val: int, bark_power: int32):
self.name_val = name_val
self.health = CInt32T(100)
self.health = int32(100)
self.bark_power = bark_power
def speak(self) -> CInt:
def speak(self) -> int:
return 1
def bite(self) -> CInt32T:
def bite(self) -> int32:
return self.bark_power
def take_damage(self, dmg: CInt32T) -> 'Dog' | CPtr:
def take_damage(self, dmg: int32) -> Dog*:
self.health = self.health - dmg
return self
def is_alive(self) -> CInt:
def is_alive(self) -> int:
if self.health > 0:
return 1
return 0
@t.CVTable
class Cat:
name_val: CInt
health: CInt32T
lives: CInt32T
virtual class Cat:
name_val: int
health: int32
lives: int32
def __init__(self, name_val: CInt, lives: CInt32T):
def __init__(self, name_val: int, lives: int32):
self.name_val = name_val
self.health = CInt32T(80)
self.health = int32(80)
self.lives = lives
def speak(self) -> CInt:
def speak(self) -> int:
return 2
def scratch(self) -> CInt32T:
return CInt32T(15)
def take_damage(self, dmg: CInt32T) -> 'Cat' | CPtr:
def scratch(self) -> int32:
return int32(15)
def take_damage(self, dmg: int32) -> Cat*:
self.health = self.health - dmg
return self
def is_alive(self) -> CInt:
def is_alive(self) -> int:
if self.health > 0:
return 1
return 0
@@ -183,17 +176,17 @@ class Cat:
# === nested object composition (heap allocated) ===
class Transform:
px: CFloat64T
py: CFloat64T
pz: CFloat64T
scale_x: CFloat64T
scale_y: CFloat64T
scale_z: CFloat64T
px: double
py: double
pz: double
scale_x: double
scale_y: double
scale_z: double
def __new__() -> 'Transform' | CPtr:
def __new__() -> Transform*:
return stdlib.malloc(48)
def __init__(self, px: CFloat64T, py: CFloat64T, pz: CFloat64T):
def __init__(self, px: double, py: double, pz: double):
self.px = px
self.py = py
self.pz = pz
@@ -201,68 +194,65 @@ class Transform:
self.scale_y = 1.0
self.scale_z = 1.0
def apply_scale(self, sx: CFloat64T, sy: CFloat64T, sz: CFloat64T) -> 'Transform' | CPtr:
def apply_scale(self, sx: double, sy: double, sz: double) -> Transform*:
self.scale_x = self.scale_x * sx
self.scale_y = self.scale_y * sy
self.scale_z = self.scale_z * sz
return self
def world_position(self) -> 'Vec3' | CPtr:
def world_position(self) -> Vec3*:
return Vec3(self.px * self.scale_x, self.py * self.scale_y, self.pz * self.scale_z)
# === multilevel inheritance (subclasses override only what they need) ===
@t.CVTable
class Vehicle:
speed: CInt32T
fuel: CInt32T
virtual class Vehicle:
speed: int32
fuel: int32
def __init__(self, speed: CInt32T):
def __init__(self, speed: int32):
self.speed = speed
self.fuel = CInt32T(100)
def move(self) -> CInt:
self.fuel = self.fuel - CInt32T(10)
self.fuel = int32(100)
def move(self) -> int:
self.fuel = self.fuel - int32(10)
return self.speed
def is_running(self) -> CInt:
def is_running(self) -> int:
if self.fuel > 0:
return 1
return 0
@t.CVTable
class Car(Vehicle):
doors: CInt32T
virtual class Car(Vehicle):
doors: int32
def __init__(self, speed: CInt32T, doors: CInt32T):
def __init__(self, speed: int32, doors: int32):
self.speed = speed
self.fuel = CInt32T(100)
self.fuel = int32(100)
self.doors = doors
def honk(self) -> CInt:
def honk(self) -> int:
return 1
@t.CVTable
class ElectricCar(Car):
battery: CInt32T
virtual class ElectricCar(Car):
battery: int32
def __init__(self, speed: CInt32T, doors: CInt32T, battery: CInt32T):
def __init__(self, speed: int32, doors: int32, battery: int32):
self.speed = speed
self.fuel = CInt32T(100)
self.fuel = int32(100)
self.doors = doors
self.battery = battery
def charge(self):
self.battery = self.battery + CInt32T(20)
def move(self) -> CInt:
self.battery = self.battery - CInt32T(5)
self.battery = self.battery + int32(20)
def move(self) -> int:
self.battery = self.battery - int32(5)
return self.speed
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
testcheck.begin("OopInheritTest: OOP 继承与多态专项测试")
buf: CChar | CPtr = CPtr(stdlib.malloc(256))
buf: str = stdlib.malloc(256)
# === OOP inheritance test ===
testcheck.section("OOP 继承测试")
@@ -351,19 +341,19 @@ def main() -> CInt | CExport:
# === Dog/Cat virtual methods ===
testcheck.section("Dog/Cat 虚方法")
dog = Dog(1, CInt32T(30))
cat = Cat(2, CInt32T(9))
dog = Dog(1, int32(30))
cat = Cat(2, int32(9))
viperlib.snprintf(buf, 256, "Dog speak=%d bite=%d alive=%d", dog.speak(), dog.bite(), dog.is_alive())
print(buf)
viperlib.snprintf(buf, 256, "Cat speak=%d scratch=%d alive=%d", cat.speak(), cat.scratch(), cat.is_alive())
print(buf)
dog.take_damage(CInt32T(40)).take_damage(CInt32T(30))
dog.take_damage(int32(40)).take_damage(int32(30))
viperlib.snprintf(buf, 256, "Dog after 70dmg: health=%d alive=%d", dog.health, dog.is_alive())
print(buf)
cat.take_damage(CInt32T(50))
cat.take_damage(int32(50))
viperlib.snprintf(buf, 256, "Cat after 50dmg: health=%d alive=%d", cat.health, cat.is_alive())
print(buf)
testcheck.ok("Dog/Cat 虚方法测试完成")
@@ -385,7 +375,7 @@ def main() -> CInt | CExport:
# === multilevel inheritance ===
testcheck.section("多层继承")
ec = ElectricCar(CInt32T(120), CInt32T(4), CInt32T(80))
ec = ElectricCar(int32(120), int32(4), int32(80))
viperlib.snprintf(buf, 256, "ECar speed=%d doors=%d battery=%d", ec.speed, ec.doors, ec.battery)
print(buf)
ec.charge()
+7 -9
View File
@@ -1,5 +1,3 @@
from stdint import *
import t, c
import stdio
import string
import win32.win32console
@@ -69,7 +67,7 @@ def test_pointer_arithmetic():
# --- Test 3: array decay to pointer ---
def test_array_decay():
"""Pass list[t.CChar, N] to a t.CConst | str parameter."""
arr: t.CArray[char, 32]
arr: [32]char
string.memset(&arr, 0, 32)
# Write string manually
src: str = "Hello"
@@ -121,7 +119,7 @@ def test_pointer_offset():
buf[3] = 0x44 # 'D'
# Read via CUInt32T* (0x44434241 on little-endian)
p32: uint32* = (uint32*)(t.CPtr(uint64(buf)))
p32: uint32* = (uint32*)(buf)
val: uint32 = p32[0]
# little-endian: 0x44434241
@@ -164,7 +162,7 @@ def test_memcpy_pointers():
src_buf[i] = uint32(i + 1000)
# Copy
string.memcpy(t.CPtr(uint64(dst_buf)), t.CPtr(uint64(src_buf)), 32)
string.memcpy(rawptr(dst_buf), rawptr(src_buf), 32)
# Verify
ok: int = 1
@@ -196,22 +194,22 @@ def test_pointer_param():
testcheck.check(ok, "pointer as function parameter", "pointer as function parameter failed")
def main() -> int | t.CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
print("你好")
l: t.CArray[char, 2] = None
l: [2]char = None
for i in "hello":
l[0] = i
print(l)
#u: t.CArray[t.CUInt64T | t.BigEndian, 2] = [0x4141414141414141, 0x0000000000000000]
#u: [2]bigend uint64 = [0x4141414141414141, 0x0000000000000000]
#for i in c.Addr(u):
# # l[0] = i
# stdio.printf("0x%llx\n", i)
k: t.CArray[char, 12] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C']
k: [12]char = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C']
for i in k:
stdio.printf("%c\n", i)
+3 -5
View File
@@ -7,9 +7,8 @@
# Gen 2: ViperC\__vpcbuild__\output\viperc.exe --project Test\ProbeGen\project.vpj --clean --run --build-dir Test\ProbeGen\__vpcbuild___g2
# WARNING [P6] breaks compilation from generation 2 onward; comment out [P6] to get Gen-2 IR for P1..P5.
import t
from stdint import *
import w32.win32console as w32console
import win32.win32console as win32console
# [P1] Nested union parameter: VOIDPTR (typedef of t.CPtr) unioned with t.CPtr gives i8** on one side, i8* on the other.
@@ -18,7 +17,7 @@ extern def ProbeNestedUnion(Context: VOIDPTR*) -> BOOL
# [P2] Struct by-value parameter: COORD without | t.CPtr gives %COORD on one side, %COORD* on the other.
extern def ProbeCoordByVal(dwSize: w32console.COORD) -> BOOL
extern def ProbeCoordByVal(dwSize: win32console.COORD) -> BOOL
# [P5] Sink for the local uint8 = 1 literal: store it into a global so the code is not dead-code eliminated.
@@ -61,8 +60,7 @@ class Box:
# Entry: keep main minimal, referencing each construct above so it is really translated; return 0.
# P1/P2 are extern declarations and are not called, so their difference shows in this module's declares.
@t.CExport
def main() -> int:
export def main() -> int:
Ch: char = 'A'
BoxInst: Box = Box()
BoxInst.Clear()
+2 -3
View File
@@ -1,4 +1,3 @@
import t, c
from stdint import *
import stdio
import stdlib
@@ -86,9 +85,9 @@ def main() -> int:
w: uint64 = 0
pw: uint64* = &w
*pw = 0x1234
blk: t.CPtr = t.CPtr(uint64(pw))
blk: rawptr = rawptr(uint64(pw))
hd1: uint64 = *((uint64*)(blk))
hd2: uint64 = uint64(t.CPtr(*((uint64*)(blk))))
hd2: uint64 = uint64(rawptr(*((uint64*)(blk))))
if hd1 != 0x1234:
stdio.printf("FAIL I1 直接读块头 : hd1=0x%llX(期望 0x1234)\n", hd1)
fails += 1
+6 -7
View File
@@ -1,24 +1,23 @@
import t, c
from stdint import *
import stdio
# Module-level global fixed-size array (rawarray mirrors t.CArray)
g_arr: rawarray[int, 4] = [10, 20, 30, 40]
g_arr: [4]int = [10, 20, 30, 40]
# Struct with embedded fixed-size array fields
class Ctx:
state: rawarray[uint32, 5]
buf: rawarray[uint8, 64]
state: [5]uint32
buf: [64]uint8
def main() -> int | t.CExport:
export def main() -> int:
# 1) Read global array
stdio.printf("1 g_arr[0]=%d g_arr[3]=%d (expect 10 40)\n", g_arr[0], g_arr[3])
# 2) Local fixed-size array (write + read)
loc: rawarray[uint32, 3] = [0, 0, 0]
loc: [3]uint32 = [0, 0, 0]
loc[1] = 7
stdio.printf("2 loc[1]=%d (expect 7)\n", loc[1])
@@ -37,7 +36,7 @@ def main() -> int | t.CExport:
return 0
def sum_arr(vals: rawarray[uint32, 3], n: int) -> int:
def sum_arr(vals: [3]uint32, n: int) -> int:
s: int = 0
i: int
for i in range(n):
+1 -5
View File
@@ -1,10 +1,6 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CExport
import stdio
import stdlib
import string
import testcheck
@@ -20,7 +16,7 @@ def bump_false(buf: bytes) -> bool:
return False
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
+4 -6
View File
@@ -2,9 +2,7 @@ from stdint import *
import vipersimd
import numpy
from stdio import printf
import stdlib
from stdlib import calloc
import t, c
import memhub
import testcheck
@@ -14,7 +12,7 @@ arena: uint8* = None
pool: memhub.MemPool* = None
# External function: clock() for performance timing
def clock() -> t.CLong | t.CExtern: pass
extern def clock() -> long
define CLOCK_PER_SEC = 1000
@@ -356,21 +354,21 @@ def test_llvmir_scalar():
define N_ELEM = 40000
define N_ITER = 50000
def scalar_add_array(a: t.CPtr, b: t.CPtr, out: t.CPtr, n: sizet):
def scalar_add_array(a: rawptr, b: rawptr, out: rawptr, n: sizet):
da: double* = a
db: double* = b
dout: double* = out
for i in range(n):
dout[i] = da[i] + db[i]
def scalar_mul_array(a: t.CPtr, b: t.CPtr, out: t.CPtr, n: sizet):
def scalar_mul_array(a: rawptr, b: rawptr, out: rawptr, n: sizet):
da: double* = a
db: double* = b
dout: double* = out
for i in range(n):
dout[i] = da[i] * db[i]
def scalar_sqrt_array(a: t.CPtr, out: t.CPtr, n: sizet):
def scalar_sqrt_array(a: rawptr, out: rawptr, n: sizet):
da: double* = a
dout: double* = out
for i in range(n):
-1
View File
@@ -1,4 +1,3 @@
import t
import ast
+1 -3
View File
@@ -1,5 +1,4 @@
from stdint import *
import t, c
import stdio
import stdlib
import testcheck
@@ -8,8 +7,7 @@ import string
# SprintfTest: runtime verification of viperlib.snprintf %a/%A against glibc printf
@t.CExport
def main() -> int:
export def main() -> int:
testcheck.begin("SprintfTest: %a/%A runtime verification")
buf: bytes = stdlib.malloc(256)
+1 -3
View File
@@ -1,6 +1,4 @@
import t
import stdio
import c
# Test: class with inline list[struct, N] field
@@ -9,7 +7,7 @@ class Inner:
bits: int
class Container:
items: t.CArray[Inner, 10]
items: [10]Inner
count: int
def __init__(self):
-1
View File
@@ -1,4 +1,3 @@
import t
import stdio
import string
import testcheck
+5 -6
View File
@@ -1,21 +1,20 @@
import t
import stdio
import string
import testcheck
import win32.win32memory
# Define structs
class Point():
struct Point:
x: int
y: int
class Rect():
struct Rect:
origin: Point
size: Point
class Node():
struct Node:
value: int
next: t.CPtr # Node* type
next: rawptr # Node* type
def test_struct_basic():
testcheck.section("Test 1: struct basic")
@@ -39,7 +38,7 @@ def test_struct_pointer():
p.x = 42
p.y = 84
# Take a struct pointer
pp: Point* = t.CPtr(uint64(p))
pp: Point* = Point*(p)
# Modify through the pointer
pp.x = 100
pp.y = 200
+26 -33
View File
@@ -1,6 +1,4 @@
from stdint import *
import t, c
from t import CPtr, CInt, CExport
import testcheck
@@ -10,81 +8,76 @@ import testcheck
# ========== Single inheritance: super().__init__ + super().method ==========
@t.CVTable
class Animal:
Tag: CInt
virtual class Animal:
Tag: int
def __init__(self, tag: CInt):
def __init__(self, tag: int):
self.Tag = tag
def Speak(self) -> CInt:
def Speak(self) -> int:
return 0
def Greet(self) -> CInt:
def Greet(self) -> int:
return self.Tag + 1000
@t.CVTable
class Dog(Animal):
Breed: CInt
virtual class Dog(Animal):
Breed: int
def __init__(self, tag: CInt, breed: CInt):
def __init__(self, tag: int, breed: int):
super().__init__(tag) # Call Animal.__init__ to set Tag
self.Breed = breed
def Speak(self) -> CInt:
def Speak(self) -> int:
return 1
def ParentSpeak(self) -> CInt:
def ParentSpeak(self) -> int:
return super().Speak() # Statically bind Animal.Speak -> 0 (no virtual dispatch)
def FullGreet(self) -> CInt:
def FullGreet(self) -> int:
# Call parent Greet (not overridden by Dog), then add own field
return super().Greet() + self.Breed
# ========== Three-level chain: Grand -> Mid -> Leaf ==========
@t.CVTable
class Grand:
G: CInt
virtual class Grand:
G: int
def __init__(self, v: CInt):
def __init__(self, v: int):
self.G = v
def Base(self) -> CInt:
def Base(self) -> int:
return self.G
@t.CVTable
class Mid(Grand):
M: CInt
virtual class Mid(Grand):
M: int
def __init__(self, v: CInt):
def __init__(self, v: int):
super().__init__(v + 1) # Call Grand.__init__
self.M = v
def MidOnly(self) -> CInt:
def MidOnly(self) -> int:
return self.M
@t.CVTable
class Leaf(Mid):
def __init__(self, v: CInt):
virtual class Leaf(Mid):
def __init__(self, v: int):
super().__init__(v + 2) # Call Mid.__init__ (which supers to Grand)
def GetBase(self) -> CInt:
def GetBase(self) -> int:
return super().Base() # Mid has no Base -> find Grand.Base along MRO
def CallMidOnly(self) -> CInt:
def CallMidOnly(self) -> int:
return super().MidOnly() # Call Mid.MidOnly
def main() -> CInt | CExport:
export def main() -> int:
testcheck.begin("SuperTest: super() 语义测试")
# --- 1. super().__init__ sets parent fields ---
d: Dog | CPtr = Dog(42, 7)
d: Dog* = Dog(42, 7)
testcheck.check(d.Tag == 42, "super().__init__ 设置父类字段 OK",
"super().__init__ FAILED")
testcheck.check(d.Breed == 7, "子类字段 OK", "子类字段 FAILED")
@@ -99,7 +92,7 @@ def main() -> CInt | CExport:
"FullGreet() FAILED")
# --- 4. three-level super().__init__ chain (Leaf(10) -> Mid(12) -> Grand(13)) ---
lf: Leaf | CPtr = Leaf(10)
lf: Leaf* = Leaf(10)
testcheck.check(lf.G == 13, "三层 super().__init__ 链 G OK", "三层 G FAILED")
testcheck.check(lf.M == 12, "中间类 M OK", "中间类 M FAILED")
+1 -3
View File
@@ -1,7 +1,5 @@
from stdint import *
import win32.win32console
import t, c
from t import CInt, CExport
import memhub
import stdlib
import sys
@@ -18,7 +16,7 @@ import syslibtest_impl
define ARENA_SIZE = 1048576
def main() -> CInt | CExport:
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
-1
View File
@@ -1,4 +1,3 @@
import t, c
from stdint import *
import platmacro
import os._win32
Loaded 100 of 112 files, more files were not shown because too many files have changed in this diff. Show more