去除 import t, c
This commit is contained in:
1 parent
579cf8d8e0
commit
e67b80c083
112 files changed
+1235
-1347
No files matched your search
@@ -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
@@ -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,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
@@ -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")
|
||||
|
||||
@@ -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
@@ -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
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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")
|
||||
|
||||
@@ -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,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")
|
||||
|
||||
@@ -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,4 +1,3 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
import stdio
|
||||
import coro
|
||||
|
||||
+33
-46
@@ -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,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
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import t
|
||||
import stdio
|
||||
import string
|
||||
import c
|
||||
import testcheck
|
||||
import remote
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import t
|
||||
|
||||
|
||||
def remote_func() -> int:
|
||||
"Remote function docstring."
|
||||
return 0
|
||||
|
||||
@@ -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
@@ -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
@@ -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,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
@@ -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)
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
from stdint import *
|
||||
import t, c
|
||||
import stdio
|
||||
import testcheck
|
||||
|
||||
|
||||
|
||||
+3
-13
@@ -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():
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,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()
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import t
|
||||
import c
|
||||
import stdio
|
||||
import stdlib
|
||||
import string
|
||||
import memhub
|
||||
import testcheck
|
||||
|
||||
|
||||
@@ -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
@@ -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):
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import t
|
||||
import stdio
|
||||
import stdlib
|
||||
import memhub
|
||||
from g4node import G4Node, new_g4node
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import t
|
||||
import stdio
|
||||
import stdlib
|
||||
import memhub
|
||||
from g4node import G4Node, new_g4node
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import t
|
||||
import stdio
|
||||
import stdlib
|
||||
import memhub
|
||||
from g4node import G4Node, new_g4node
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import t
|
||||
import stdio
|
||||
import testcheck
|
||||
import stdlib
|
||||
|
||||
+2
-6
@@ -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*):
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import t, c
|
||||
import stdio
|
||||
import testcheck
|
||||
import atom
|
||||
|
||||
|
||||
+1
-3
@@ -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():
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import t
|
||||
import stdio
|
||||
import testcheck
|
||||
|
||||
# Test 1: generic function with explicit type arg - basic call
|
||||
|
||||
+11
-13
@@ -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
@@ -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,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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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")
|
||||
|
||||
|
||||
@@ -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,4 +1,3 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
from stdio import printf
|
||||
import memhub
|
||||
|
||||
+11
-13
@@ -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")
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import t, c
|
||||
|
||||
|
||||
define POSMAX = 100
|
||||
define MAX_RETRY = 5
|
||||
define BUFFER_SIZE = 256
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import t, c
|
||||
import config
|
||||
import logic_test
|
||||
import testcheck
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import t, c
|
||||
|
||||
|
||||
define POSMAX = 100
|
||||
define MAX_RETRY = 5
|
||||
define BUFFER_SIZE = 256
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import config
|
||||
import test
|
||||
import testcheck
|
||||
|
||||
@@ -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,7 +1,6 @@
|
||||
import t
|
||||
import stdio
|
||||
import testcheck
|
||||
|
||||
|
||||
def test_for_loop():
|
||||
testcheck.section("Test 1: for loop")
|
||||
sum_val: int = 0
|
||||
|
||||
@@ -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
@@ -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,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()
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,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:
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
import t, c
|
||||
|
||||
def h(x: int) -> int:
|
||||
x = x + 1
|
||||
@@ -1,4 +1,2 @@
|
||||
import t, c
|
||||
|
||||
def main() -> int:
|
||||
return foo(1)
|
||||
@@ -1,5 +1,3 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
import stdio
|
||||
|
||||
def main() -> int:
|
||||
|
||||
+128
-130
@@ -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")
|
||||
|
||||
@@ -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 由编译器在函数出口释放
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import t
|
||||
import stdio
|
||||
import string
|
||||
import testcheck
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import t
|
||||
import stdio
|
||||
import string
|
||||
import testcheck
|
||||
import linkedlist
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
|
||||
@@ -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,4 +1,3 @@
|
||||
import t
|
||||
import ast
|
||||
|
||||
|
||||
|
||||
@@ -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,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,4 +1,3 @@
|
||||
import t
|
||||
import stdio
|
||||
import string
|
||||
import testcheck
|
||||
|
||||
@@ -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
@@ -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,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,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
Reference in new issue
Block a user