去除 import t, c

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

No files matched your search

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