Initial import of TransPyV
This commit is contained in:
47
Test/App/asm_test.py
Normal file
47
Test/App/asm_test.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# c.Asm 内联汇编测试
|
||||
# ============================================================
|
||||
|
||||
def asm_test() -> int:
|
||||
# 1. 简单无操作数汇编(nop + clobber)
|
||||
c.Asm("nop", op=[t.ASM_DESCR.CLOBBER_MEMORY])
|
||||
stdio.printf("asm: nop ok\n")
|
||||
|
||||
# 2. 仅汇编文本无 clobber
|
||||
c.Asm("nop")
|
||||
stdio.printf("asm: nop2 ok\n")
|
||||
|
||||
# 3. 多 clobber
|
||||
c.Asm("nop", op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_CC])
|
||||
stdio.printf("asm: multi-clobber ok\n")
|
||||
|
||||
# 4. 带输入操作数的汇编(读取 CPU ID)
|
||||
# 使用 f-string 内联 c.AsmInp
|
||||
# mov eax, 输入值; nop(保持简单,不使用会产生异常的指令)
|
||||
val: int = 42
|
||||
c.Asm(f"""mov eax, {c.AsmInp(val, t.ASM_DESCR.REG_ANY)}
|
||||
nop""", op=[t.ASM_DESCR.CLOBBER_RAX])
|
||||
stdio.printf("asm: input ok val=%d\n", val)
|
||||
|
||||
# 5. 带输出操作数的汇编
|
||||
# c.AsmOut 获取结果
|
||||
result: int = 0
|
||||
c.Asm(f"""mov {c.AsmOut(result, t.ASM_DESCR.OUTPUT_REG)}, 123
|
||||
nop""", op=[t.ASM_DESCR.CLOBBER_RAX])
|
||||
stdio.printf("asm: output result=%d\n", result)
|
||||
|
||||
# 6. 带输入和输出操作数
|
||||
# result2 = val + 1
|
||||
result2: int = 0
|
||||
input_val: int = 10
|
||||
c.Asm(f"""mov eax, {c.AsmInp(input_val, t.ASM_DESCR.REG_ANY)}
|
||||
add eax, 1
|
||||
mov {c.AsmOut(result2, t.ASM_DESCR.OUTPUT_REG)}, eax
|
||||
nop""", op=[t.ASM_DESCR.CLOBBER_RAX])
|
||||
stdio.printf("asm: in+out result2=%d (expect 11)\n", result2)
|
||||
|
||||
return 0
|
||||
234
Test/App/attr_test.py
Normal file
234
Test/App/attr_test.py
Normal file
@@ -0,0 +1,234 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
import stdio
|
||||
import string
|
||||
|
||||
|
||||
# ============================================================
|
||||
# c.Attribute 装饰器测试
|
||||
#
|
||||
# 测试 @c.Attribute(...) 对函数属性的设置:
|
||||
# - t.attr.always_inline() -> alwaysinline
|
||||
# - t.attr.noinline() -> noinline
|
||||
# - t.attr.noreturn() -> noreturn
|
||||
# - t.attr.pure() -> readonly (LLVM 函数属性)
|
||||
# - t.attr.llvm.nounwind -> nounwind
|
||||
# ============================================================
|
||||
|
||||
|
||||
# Test 1: always_inline 属性
|
||||
@c.Attribute(t.attr.always_inline())
|
||||
def AlwaysInlineFunc(x: t.CInt) -> t.CInt:
|
||||
return x * 2
|
||||
|
||||
|
||||
# Test 2: noinline 属性
|
||||
@c.Attribute(t.attr.noinline())
|
||||
def NoInlineFunc(x: t.CInt) -> t.CInt:
|
||||
return x + 100
|
||||
|
||||
|
||||
# Test 3: noreturn 属性(函数确实不返回)
|
||||
@c.Attribute(t.attr.noreturn())
|
||||
def NoReturnFunc() -> t.CInt:
|
||||
stdio.printf("NoReturnFunc called (does not return)\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 4: 普通函数对照(无装饰器)
|
||||
def NormalFunc(x: t.CInt) -> t.CInt:
|
||||
return x * 3
|
||||
|
||||
|
||||
# Test 5: 多属性组合
|
||||
@c.Attribute(t.attr.always_inline(), t.attr.pure())
|
||||
def MultiAttrFunc(x: t.CInt) -> t.CInt:
|
||||
return x + 1
|
||||
|
||||
|
||||
# Test 6: 无括号属性引用 t.attr.packed
|
||||
@c.Attribute(t.attr.packed)
|
||||
def PackedAttrFunc(x: t.CInt) -> t.CInt:
|
||||
return x - 1
|
||||
|
||||
|
||||
def test_always_inline() -> t.CInt:
|
||||
stdio.printf("--- Test 1: c.Attribute(always_inline) ---\n")
|
||||
r: t.CInt = AlwaysInlineFunc(21)
|
||||
stdio.printf("AlwaysInlineFunc(21)=%d (expect 42)\n", r)
|
||||
if r == 42:
|
||||
stdio.printf("AlwaysInlineFunc OK\n")
|
||||
else:
|
||||
stdio.printf("AlwaysInlineFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_noinline() -> t.CInt:
|
||||
stdio.printf("--- Test 2: c.Attribute(noinline) ---\n")
|
||||
r: t.CInt = NoInlineFunc(5)
|
||||
stdio.printf("NoInlineFunc(5)=%d (expect 105)\n", r)
|
||||
if r == 105:
|
||||
stdio.printf("NoInlineFunc OK\n")
|
||||
else:
|
||||
stdio.printf("NoInlineFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_noreturn() -> t.CInt:
|
||||
stdio.printf("--- Test 3: c.Attribute(noreturn) ---\n")
|
||||
stdio.printf("NoReturnFunc declared with noreturn attr\n")
|
||||
stdio.printf("NoReturnFunc OK (not called to avoid UB)\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_normal() -> t.CInt:
|
||||
stdio.printf("--- Test 4: normal function (no attr) ---\n")
|
||||
r: t.CInt = NormalFunc(7)
|
||||
stdio.printf("NormalFunc(7)=%d (expect 21)\n", r)
|
||||
if r == 21:
|
||||
stdio.printf("NormalFunc OK\n")
|
||||
else:
|
||||
stdio.printf("NormalFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_multi_attr() -> t.CInt:
|
||||
stdio.printf("--- Test 5: c.Attribute(always_inline, pure) ---\n")
|
||||
r: t.CInt = MultiAttrFunc(10)
|
||||
stdio.printf("MultiAttrFunc(10)=%d (expect 11)\n", r)
|
||||
if r == 11:
|
||||
stdio.printf("MultiAttrFunc OK\n")
|
||||
else:
|
||||
stdio.printf("MultiAttrFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_packed_attr() -> t.CInt:
|
||||
stdio.printf("--- Test 6: c.Attribute(packed) ---\n")
|
||||
r: t.CInt = PackedAttrFunc(10)
|
||||
stdio.printf("PackedAttrFunc(10)=%d (expect 9)\n", r)
|
||||
if r == 9:
|
||||
stdio.printf("PackedAttrFunc OK\n")
|
||||
else:
|
||||
stdio.printf("PackedAttrFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 7: t.attr.llvm.nounwind 属性
|
||||
@c.Attribute(t.attr.llvm.nounwind)
|
||||
def NoUnwindFunc(x: t.CInt) -> t.CInt:
|
||||
return x + 1
|
||||
|
||||
|
||||
# Test 8: t.attr.llvm.noredzone 属性
|
||||
@c.Attribute(t.attr.llvm.noredzone)
|
||||
def NoRedZoneFunc(x: t.CInt) -> t.CInt:
|
||||
return x + 2
|
||||
|
||||
|
||||
# Test 9: t.attr.llvm.willreturn 属性
|
||||
@c.Attribute(t.attr.llvm.willreturn)
|
||||
def WillReturnFunc(x: t.CInt) -> t.CInt:
|
||||
return x + 3
|
||||
|
||||
|
||||
# Test 10: t.attr.llvm.mustprogress 属性
|
||||
@c.Attribute(t.attr.llvm.mustprogress)
|
||||
def MustProgressFunc(x: t.CInt) -> t.CInt:
|
||||
return x + 4
|
||||
|
||||
|
||||
# Test 11: t.attr.const() -> readnone
|
||||
@c.Attribute(t.attr.const())
|
||||
def ConstFunc(x: t.CInt) -> t.CInt:
|
||||
return x * 0 + 42
|
||||
|
||||
|
||||
# Test 12: 多属性组合(alwaysinline + nounwind + noredzone)
|
||||
@c.Attribute(t.attr.always_inline(), t.attr.llvm.nounwind, t.attr.llvm.noredzone)
|
||||
def TripleAttrFunc(x: t.CInt) -> t.CInt:
|
||||
return x + 5
|
||||
|
||||
|
||||
def test_nounwind() -> t.CInt:
|
||||
stdio.printf("--- Test 7: c.Attribute(llvm.nounwind) ---\n")
|
||||
r: t.CInt = NoUnwindFunc(10)
|
||||
stdio.printf("NoUnwindFunc(10)=%d (expect 11)\n", r)
|
||||
if r == 11:
|
||||
stdio.printf("NoUnwindFunc OK\n")
|
||||
else:
|
||||
stdio.printf("NoUnwindFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_noredzone() -> t.CInt:
|
||||
stdio.printf("--- Test 8: c.Attribute(llvm.noredzone) ---\n")
|
||||
r: t.CInt = NoRedZoneFunc(10)
|
||||
stdio.printf("NoRedZoneFunc(10)=%d (expect 12)\n", r)
|
||||
if r == 12:
|
||||
stdio.printf("NoRedZoneFunc OK\n")
|
||||
else:
|
||||
stdio.printf("NoRedZoneFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_willreturn() -> t.CInt:
|
||||
stdio.printf("--- Test 9: c.Attribute(llvm.willreturn) ---\n")
|
||||
r: t.CInt = WillReturnFunc(10)
|
||||
stdio.printf("WillReturnFunc(10)=%d (expect 13)\n", r)
|
||||
if r == 13:
|
||||
stdio.printf("WillReturnFunc OK\n")
|
||||
else:
|
||||
stdio.printf("WillReturnFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_mustprogress() -> t.CInt:
|
||||
stdio.printf("--- Test 10: c.Attribute(llvm.mustprogress) ---\n")
|
||||
r: t.CInt = MustProgressFunc(10)
|
||||
stdio.printf("MustProgressFunc(10)=%d (expect 14)\n", r)
|
||||
if r == 14:
|
||||
stdio.printf("MustProgressFunc OK\n")
|
||||
else:
|
||||
stdio.printf("MustProgressFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_const_attr() -> t.CInt:
|
||||
stdio.printf("--- Test 11: c.Attribute(const) ---\n")
|
||||
r: t.CInt = ConstFunc(99)
|
||||
stdio.printf("ConstFunc(99)=%d (expect 42)\n", r)
|
||||
if r == 42:
|
||||
stdio.printf("ConstFunc OK\n")
|
||||
else:
|
||||
stdio.printf("ConstFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def test_triple_attr() -> t.CInt:
|
||||
stdio.printf("--- Test 12: c.Attribute(always_inline, nounwind, noredzone) ---\n")
|
||||
r: t.CInt = TripleAttrFunc(10)
|
||||
stdio.printf("TripleAttrFunc(10)=%d (expect 15)\n", r)
|
||||
if r == 15:
|
||||
stdio.printf("TripleAttrFunc OK\n")
|
||||
else:
|
||||
stdio.printf("TripleAttrFunc FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def attr_test() -> t.CInt:
|
||||
stdio.printf("=== attr_test: c.Attribute 装饰器测试 ===\n\n")
|
||||
test_always_inline()
|
||||
test_noinline()
|
||||
test_noreturn()
|
||||
test_normal()
|
||||
test_multi_attr()
|
||||
test_packed_attr()
|
||||
test_nounwind()
|
||||
test_noredzone()
|
||||
test_willreturn()
|
||||
test_mustprogress()
|
||||
test_const_attr()
|
||||
test_triple_attr()
|
||||
stdio.printf("\n=== attr_test 完成 ===\n")
|
||||
return 0
|
||||
58
Test/App/augassign_test.py
Normal file
58
Test/App/augassign_test.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AugAssign 测试:+= -= *= /= %= &= |= ^= <<= >>=
|
||||
# ============================================================
|
||||
|
||||
g_count: int = 0
|
||||
|
||||
|
||||
def test_local() -> int:
|
||||
x: int = 10
|
||||
x += 5
|
||||
stdio.printf("local +=: %d\n", x)
|
||||
x -= 3
|
||||
stdio.printf("local -=: %d\n", x)
|
||||
x *= 2
|
||||
stdio.printf("local *=: %d\n", x)
|
||||
x /= 4
|
||||
stdio.printf("local /=: %d\n", x)
|
||||
x %= 7
|
||||
stdio.printf("local %%=: %d\n", x)
|
||||
return 0
|
||||
|
||||
|
||||
def test_global_aug() -> int:
|
||||
global g_count
|
||||
g_count += 1
|
||||
stdio.printf("global +=: %d\n", g_count)
|
||||
g_count += 10
|
||||
stdio.printf("global +=: %d\n", g_count)
|
||||
g_count -= 3
|
||||
stdio.printf("global -=: %d\n", g_count)
|
||||
return 0
|
||||
|
||||
|
||||
def test_bitops() -> int:
|
||||
b: int = 0xFF
|
||||
b &= 0x0F
|
||||
stdio.printf("bit &=: %d\n", b)
|
||||
b |= 0x30
|
||||
stdio.printf("bit |=: %d\n", b)
|
||||
b ^= 0xFF
|
||||
stdio.printf("bit ^=: %d\n", b)
|
||||
b = 1
|
||||
b <<= 4
|
||||
stdio.printf("bit <<=: %d\n", b)
|
||||
b >>= 2
|
||||
stdio.printf("bit >>=: %d\n", b)
|
||||
return 0
|
||||
|
||||
|
||||
def augassign_test() -> int:
|
||||
test_local()
|
||||
test_global_aug()
|
||||
test_bitops()
|
||||
return 0
|
||||
45
Test/App/closure_test.py
Normal file
45
Test/App/closure_test.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 闭包 + nonlocal/global 测试
|
||||
# ============================================================
|
||||
|
||||
# 全局变量
|
||||
g_count: int = 0
|
||||
|
||||
|
||||
# global 关键字测试:修改全局变量
|
||||
def test_global() -> int:
|
||||
global g_count
|
||||
g_count = g_count + 1
|
||||
return g_count
|
||||
|
||||
|
||||
# nonlocal 关键字测试:嵌套函数修改外层局部变量
|
||||
def make_counter() -> t.CPtr:
|
||||
count: int = 0
|
||||
|
||||
# 内部函数(闭包)捕获 count
|
||||
def counter() -> int:
|
||||
nonlocal count
|
||||
count = count + 1
|
||||
return count
|
||||
|
||||
return counter
|
||||
|
||||
|
||||
def closure_test() -> int:
|
||||
# global 测试
|
||||
stdio.printf("global: %d\n", test_global())
|
||||
stdio.printf("global: %d\n", test_global())
|
||||
stdio.printf("global: %d\n", test_global())
|
||||
|
||||
# nonlocal/闭包测试
|
||||
f: t.CPtr = make_counter()
|
||||
stdio.printf("closure: %d\n", f())
|
||||
stdio.printf("closure: %d\n", f())
|
||||
stdio.printf("closure: %d\n", f())
|
||||
|
||||
return 0
|
||||
183
Test/App/deco_test.py
Normal file
183
Test/App/deco_test.py
Normal file
@@ -0,0 +1,183 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import string
|
||||
|
||||
|
||||
# ============================================================
|
||||
# deco_test - t/c 装饰器测试
|
||||
#
|
||||
# 测试 t.CDefine / t.CExport / t.CInline / t.CExtern / t.State
|
||||
# ============================================================
|
||||
|
||||
|
||||
# Test 1: t.CDefine - 常量定义
|
||||
MAX_VALUE: t.CDefine = 256
|
||||
PI_APPROX: t.CDefine = 314
|
||||
# Test 10: t.CDefine 作为 t.CArray 的 count
|
||||
ARR_SIZE: t.CDefine = 8
|
||||
|
||||
|
||||
# Test 2: t.CExport - 导出函数标记
|
||||
def ExportedAdd(a: t.CInt, b: t.CInt) -> t.CInt | t.CExport:
|
||||
return a + b
|
||||
|
||||
|
||||
# Test 3: t.CInline - 内联函数标记
|
||||
def InlineSquare(x: t.CInt) -> t.CInt | t.CInline:
|
||||
return x * x
|
||||
|
||||
|
||||
# Test 4: 普通函数(无装饰器,作为对照)
|
||||
def NormalSub(a: t.CInt, b: t.CInt) -> t.CInt:
|
||||
return a - b
|
||||
|
||||
|
||||
# Test 5: t.CExport 与 t.CInline 组合
|
||||
def ExportedInlineCube(x: t.CInt) -> t.CInt | t.CExport | t.CInline:
|
||||
return x * x * x
|
||||
|
||||
|
||||
# Test 6: t.CExport 返回指针
|
||||
def ExportedFindChar(s: str, ch: t.CInt) -> str | t.CExport:
|
||||
return string.strchr(s, ch)
|
||||
|
||||
|
||||
def test_cdefine():
|
||||
stdio.printf("--- Test 1: t.CDefine ---\n")
|
||||
stdio.printf("MAX_VALUE=%d (expect 256)\n", MAX_VALUE)
|
||||
stdio.printf("PI_APPROX=%d (expect 314)\n", PI_APPROX)
|
||||
if MAX_VALUE == 256:
|
||||
stdio.printf("MAX_VALUE OK\n")
|
||||
else:
|
||||
stdio.printf("MAX_VALUE FAIL\n")
|
||||
if PI_APPROX == 314:
|
||||
stdio.printf("PI_APPROX OK\n")
|
||||
else:
|
||||
stdio.printf("PI_APPROX FAIL\n")
|
||||
|
||||
|
||||
def test_cexport():
|
||||
stdio.printf("--- Test 2: t.CExport ---\n")
|
||||
r: t.CInt = ExportedAdd(3, 4)
|
||||
stdio.printf("ExportedAdd(3,4)=%d (expect 7)\n", r)
|
||||
if r == 7:
|
||||
stdio.printf("ExportedAdd OK\n")
|
||||
else:
|
||||
stdio.printf("ExportedAdd FAIL\n")
|
||||
|
||||
|
||||
def test_cinline():
|
||||
stdio.printf("--- Test 3: t.CInline ---\n")
|
||||
r: t.CInt = InlineSquare(5)
|
||||
stdio.printf("InlineSquare(5)=%d (expect 25)\n", r)
|
||||
if r == 25:
|
||||
stdio.printf("InlineSquare OK\n")
|
||||
else:
|
||||
stdio.printf("InlineSquare FAIL\n")
|
||||
|
||||
|
||||
def test_deco_normal():
|
||||
stdio.printf("--- Test 4: normal function ---\n")
|
||||
r: t.CInt = NormalSub(10, 3)
|
||||
stdio.printf("NormalSub(10,3)=%d (expect 7)\n", r)
|
||||
if r == 7:
|
||||
stdio.printf("NormalSub OK\n")
|
||||
else:
|
||||
stdio.printf("NormalSub FAIL\n")
|
||||
|
||||
|
||||
def test_export_inline():
|
||||
stdio.printf("--- Test 5: t.CExport | t.CInline ---\n")
|
||||
r: t.CInt = ExportedInlineCube(3)
|
||||
stdio.printf("ExportedInlineCube(3)=%d (expect 27)\n", r)
|
||||
if r == 27:
|
||||
stdio.printf("ExportedInlineCube OK\n")
|
||||
else:
|
||||
stdio.printf("ExportedInlineCube FAIL\n")
|
||||
|
||||
|
||||
def test_export_ptr():
|
||||
stdio.printf("--- Test 6: t.CExport return ptr ---\n")
|
||||
p: str = ExportedFindChar("Hello", 108) # 'l' = 108
|
||||
if p is not None:
|
||||
stdio.printf("ExportedFindChar found, char=%d (expect 108)\n", c.Deref(p))
|
||||
if c.Deref(p) == 108:
|
||||
stdio.printf("ExportedFindChar OK\n")
|
||||
else:
|
||||
stdio.printf("ExportedFindChar FAIL\n")
|
||||
else:
|
||||
stdio.printf("ExportedFindChar NOT FOUND (FAIL)\n")
|
||||
|
||||
|
||||
# Test 7: t.CExtern | t.CExport - 外部声明函数(pass 体)
|
||||
# 声明一个外部函数,翻译器应生成 declare 而非 define
|
||||
def ExternalDecl(x: t.CInt) -> t.CInt | t.CExtern | t.CExport: pass
|
||||
|
||||
|
||||
# Test 8: t.State - 状态声明(等价于 CExtern | CExport)
|
||||
def StateDecl(x: t.CInt) -> t.CInt | t.State: pass
|
||||
|
||||
|
||||
# Test 9: t.State 返回 void
|
||||
def StateVoidDecl() -> t.State: pass
|
||||
|
||||
|
||||
def test_extern_decl():
|
||||
stdio.printf("--- Test 7: t.CExtern | t.CExport ---\n")
|
||||
# 外部声明函数,不调用(应由链接器解析符号)
|
||||
stdio.printf("ExternalDecl declared (not called)\n")
|
||||
stdio.printf("ExternalDecl OK\n")
|
||||
|
||||
|
||||
def test_state_decl():
|
||||
stdio.printf("--- Test 8: t.State ---\n")
|
||||
stdio.printf("StateDecl declared (not called)\n")
|
||||
stdio.printf("StateDecl OK\n")
|
||||
|
||||
|
||||
def test_state_void_decl():
|
||||
stdio.printf("--- Test 9: t.State (void) ---\n")
|
||||
stdio.printf("StateVoidDecl declared (not called)\n")
|
||||
stdio.printf("StateVoidDecl OK\n")
|
||||
|
||||
|
||||
# Test 10: t.CDefine 作为 t.CArray count
|
||||
# ARR_SIZE: t.CDefine = 8 已在文件顶部定义
|
||||
def test_cdefine_array_count():
|
||||
stdio.printf("--- Test 10: t.CArray[elem, CDefine] ---\n")
|
||||
# 使用 CDefine 常量名作为数组 count
|
||||
arr: t.CArray[t.CInt, ARR_SIZE]
|
||||
i: t.CInt
|
||||
# 初始化: arr[i] = i * 10
|
||||
for i in range(ARR_SIZE):
|
||||
arr[i] = i * 10
|
||||
# 求和验证: 0+10+20+...+70 = 280
|
||||
total: t.CInt = 0
|
||||
for i in range(ARR_SIZE):
|
||||
total += arr[i]
|
||||
stdio.printf("ARR_SIZE=%d (expect 8)\n", ARR_SIZE)
|
||||
stdio.printf("arr sum=%d (expect 280)\n", total)
|
||||
stdio.printf("arr[0]=%d (expect 0)\n", arr[0])
|
||||
stdio.printf("arr[7]=%d (expect 70)\n", arr[7])
|
||||
if ARR_SIZE == 8 and total == 280 and arr[0] == 0 and arr[7] == 70:
|
||||
stdio.printf("CArray CDefine count OK\n")
|
||||
else:
|
||||
stdio.printf("CArray CDefine count FAIL\n")
|
||||
|
||||
|
||||
def deco_test() -> int:
|
||||
stdio.printf("=== deco_test: t/c 装饰器测试 ===\n\n")
|
||||
|
||||
test_cdefine()
|
||||
test_cexport()
|
||||
test_cinline()
|
||||
test_deco_normal()
|
||||
test_export_inline()
|
||||
test_export_ptr()
|
||||
test_extern_decl()
|
||||
test_state_decl()
|
||||
test_state_void_decl()
|
||||
test_cdefine_array_count()
|
||||
|
||||
stdio.printf("\n=== deco_test 完成 ===\n")
|
||||
return 0
|
||||
9
Test/App/deref_min_test.py
Normal file
9
Test/App/deref_min_test.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
def deref_min_test() -> int:
|
||||
s: str = "hello"
|
||||
v: int = c.Deref(s)
|
||||
stdio.printf("deref: %d\n", v)
|
||||
return 0
|
||||
13
Test/App/deref_test.py
Normal file
13
Test/App/deref_test.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
def deref_test() -> int:
|
||||
s: str = "hello"
|
||||
sp: str = s
|
||||
slen: int = 0
|
||||
while c.Deref(sp) != 0:
|
||||
slen = slen + 1
|
||||
sp = sp + 1
|
||||
stdio.printf("ptr: len(hello)=%d\n", slen)
|
||||
return 0
|
||||
144
Test/App/eq_test.py
Normal file
144
Test/App/eq_test.py
Normal file
@@ -0,0 +1,144 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import string
|
||||
|
||||
|
||||
# ============================================================
|
||||
# eq_test - ==、!=、is、is not、None 比较测试
|
||||
#
|
||||
# 验证比较表达式的翻译,特别是 None 常量和 is/is not 操作符
|
||||
# ============================================================
|
||||
|
||||
|
||||
def test_int_eq():
|
||||
stdio.printf("--- Test 1: int == / != ---\n")
|
||||
|
||||
a: t.CInt = 42
|
||||
b: t.CInt = 42
|
||||
c3: t.CInt = 99
|
||||
|
||||
if a == b:
|
||||
stdio.printf("int == int (same) OK\n")
|
||||
else:
|
||||
stdio.printf("int == int (same) FAIL\n")
|
||||
|
||||
if a != c3:
|
||||
stdio.printf("int != int (diff) OK\n")
|
||||
else:
|
||||
stdio.printf("int != int (diff) FAIL\n")
|
||||
|
||||
if not (a == c3):
|
||||
stdio.printf("not (int == diff) OK\n")
|
||||
else:
|
||||
stdio.printf("not (int == diff) FAIL\n")
|
||||
|
||||
|
||||
def test_int_cmp():
|
||||
stdio.printf("--- Test 2: int < > <= >= ---\n")
|
||||
|
||||
a: t.CInt = 5
|
||||
b: t.CInt = 10
|
||||
|
||||
if a < b:
|
||||
stdio.printf("int < OK\n")
|
||||
else:
|
||||
stdio.printf("int < FAIL\n")
|
||||
|
||||
if b > a:
|
||||
stdio.printf("int > OK\n")
|
||||
else:
|
||||
stdio.printf("int > FAIL\n")
|
||||
|
||||
if a <= 5:
|
||||
stdio.printf("int <= OK\n")
|
||||
else:
|
||||
stdio.printf("int <= FAIL\n")
|
||||
|
||||
if b >= 10:
|
||||
stdio.printf("int >= OK\n")
|
||||
else:
|
||||
stdio.printf("int >= FAIL\n")
|
||||
|
||||
|
||||
def test_ptr_is_none():
|
||||
stdio.printf("--- Test 3: ptr is None / is not None ---\n")
|
||||
|
||||
# strchr 找到字符返回非空指针,找不到返回 None
|
||||
p: str = string.strchr("Hello", 108) # 'l' = 108
|
||||
if p is not None:
|
||||
stdio.printf("strchr found, is not None OK\n")
|
||||
else:
|
||||
stdio.printf("strchr found, is not None FAIL\n")
|
||||
|
||||
p2: str = string.strchr("Hello", 122) # 'z' = 122, not found
|
||||
if p2 is None:
|
||||
stdio.printf("strchr not found, is None OK\n")
|
||||
else:
|
||||
stdio.printf("strchr not found, is None FAIL\n")
|
||||
|
||||
|
||||
def test_ptr_assign_none():
|
||||
stdio.printf("--- Test 4: assign None and compare ---\n")
|
||||
|
||||
p: str = None
|
||||
if p is None:
|
||||
stdio.printf("None assign, is None OK\n")
|
||||
else:
|
||||
stdio.printf("None assign, is None FAIL\n")
|
||||
|
||||
if p is not None:
|
||||
stdio.printf("None assign, is not None FAIL\n")
|
||||
else:
|
||||
stdio.printf("None assign, is not None OK\n")
|
||||
|
||||
|
||||
def test_ptr_eq_none():
|
||||
stdio.printf("--- Test 5: ptr == None / != None ---\n")
|
||||
|
||||
p: str = string.strstr("Hello World", "World")
|
||||
if p != None:
|
||||
stdio.printf("strstr found, != None OK\n")
|
||||
else:
|
||||
stdio.printf("strstr found, != None FAIL\n")
|
||||
|
||||
p2: str = string.strstr("Hello", "xyz")
|
||||
if p2 == None:
|
||||
stdio.printf("strstr not found, == None OK\n")
|
||||
else:
|
||||
stdio.printf("strstr not found, == None FAIL\n")
|
||||
|
||||
|
||||
def test_bool_logic():
|
||||
stdio.printf("--- Test 6: bool and/or ---\n")
|
||||
|
||||
a: t.CInt = 1
|
||||
b: t.CInt = 0
|
||||
|
||||
if a and b:
|
||||
stdio.printf("1 and 0 = true FAIL\n")
|
||||
else:
|
||||
stdio.printf("1 and 0 = false OK\n")
|
||||
|
||||
if a or b:
|
||||
stdio.printf("1 or 0 = true OK\n")
|
||||
else:
|
||||
stdio.printf("1 or 0 = true FAIL\n")
|
||||
|
||||
if not b:
|
||||
stdio.printf("not 0 = true OK\n")
|
||||
else:
|
||||
stdio.printf("not 0 = true FAIL\n")
|
||||
|
||||
|
||||
def eq_test() -> int:
|
||||
stdio.printf("=== eq_test: ==、!=、is、None 比较测试 ===\n\n")
|
||||
|
||||
test_int_eq()
|
||||
test_int_cmp()
|
||||
test_ptr_is_none()
|
||||
test_ptr_assign_none()
|
||||
test_ptr_eq_none()
|
||||
test_bool_logic()
|
||||
|
||||
stdio.printf("\n=== eq_test 完成 ===\n")
|
||||
return 0
|
||||
84
Test/App/float_test.py
Normal file
84
Test/App/float_test.py
Normal file
@@ -0,0 +1,84 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 联合体(t.CUnion)含浮点字段
|
||||
# ============================================================
|
||||
|
||||
class DataUnion(t.CUnion):
|
||||
i: t.CInt
|
||||
f: t.CFloat
|
||||
l: t.CInt64T
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 主函数
|
||||
# ============================================================
|
||||
def float_test() -> int:
|
||||
# ============================================================
|
||||
# 测试 1: 基本浮点变量(float / double)
|
||||
# ============================================================
|
||||
f: t.CFloat = 3.14
|
||||
stdio.printf("float: f=%f\n", f)
|
||||
|
||||
d: t.CDouble = 3.141592653589793
|
||||
stdio.printf("double: d=%lf\n", d)
|
||||
|
||||
# 重新赋值
|
||||
f = 2.5
|
||||
stdio.printf("float: f=%f\n", f)
|
||||
|
||||
# ============================================================
|
||||
# 测试 2: 联合体浮点字段
|
||||
# ============================================================
|
||||
u: DataUnion
|
||||
u.f = 3.14
|
||||
stdio.printf("union: u.f=%f\n", u.f)
|
||||
|
||||
# 写入 i 字段后,f 的值已被覆盖
|
||||
u.i = 42
|
||||
stdio.printf("union: u.i=%d (after f overwritten)\n", u.i)
|
||||
|
||||
# ============================================================
|
||||
# 测试 3: 联合体共享内存验证(float 与 int 共享)
|
||||
# ============================================================
|
||||
u2: DataUnion
|
||||
u2.i = 0
|
||||
u2.f = 1.0
|
||||
# 写入 f 后,i 的值应不再是 0
|
||||
if u2.i != 0:
|
||||
stdio.printf("union: float overwrites int verified\n")
|
||||
|
||||
# ============================================================
|
||||
# 测试 4: 浮点算术运算(fadd/fsub/fmul/fdiv/frem)
|
||||
# ============================================================
|
||||
a: t.CFloat = 1.5
|
||||
b: t.CFloat = 2.5
|
||||
stdio.printf("arith: %.2f + %.2f = %.2f\n", a, b, a + b)
|
||||
stdio.printf("arith: %.2f - %.2f = %.2f\n", a, b, a - b)
|
||||
stdio.printf("arith: %.2f * %.2f = %.2f\n", a, b, a * b)
|
||||
stdio.printf("arith: %.2f / %.2f = %.2f\n", a, b, a / b)
|
||||
|
||||
# ============================================================
|
||||
# 测试 5: double 算术运算
|
||||
# ============================================================
|
||||
x: t.CDouble = 10.0
|
||||
y: t.CDouble = 3.0
|
||||
stdio.printf("arith: %.4lf + %.4lf = %.4lf\n", x, y, x + y)
|
||||
stdio.printf("arith: %.4lf - %.4lf = %.4lf\n", x, y, x - y)
|
||||
stdio.printf("arith: %.4lf * %.4lf = %.4lf\n", x, y, x * y)
|
||||
stdio.printf("arith: %.4lf / %.4lf = %.4lf\n", x, y, x / y)
|
||||
|
||||
# ============================================================
|
||||
# 测试 6: 浮点取模 (frem)
|
||||
# ============================================================
|
||||
stdio.printf("arith: 10.0 %% 3.0 = %.4lf\n", x % y)
|
||||
|
||||
# ============================================================
|
||||
# 测试 7: int 与 float 混合运算(int 自动转 float)
|
||||
# ============================================================
|
||||
n: t.CInt = 3
|
||||
stdio.printf("arith: %d + %.2f = %.2f\n", n, a, n + a)
|
||||
|
||||
return 0
|
||||
23
Test/App/flow_test.py
Normal file
23
Test/App/flow_test.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
def flow_test() -> int:
|
||||
i: int = 0
|
||||
total: int = 0
|
||||
while i < 5:
|
||||
total = total + i
|
||||
i = i + 1
|
||||
stdio.printf("while: total=%d i=%d\n", total, i)
|
||||
|
||||
for k in range(10):
|
||||
if k == 3:
|
||||
break
|
||||
stdio.printf("break: k=%d\n", k)
|
||||
|
||||
for m in range(5):
|
||||
if m == 2:
|
||||
continue
|
||||
stdio.printf("continue: m=%d\n", m)
|
||||
|
||||
return 0
|
||||
8
Test/App/for_test.py
Normal file
8
Test/App/for_test.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
def for_test() -> int:
|
||||
for j in range(5):
|
||||
stdio.printf("for: j=%d\n", j)
|
||||
return 0
|
||||
68
Test/App/func_test.py
Normal file
68
Test/App/func_test.py
Normal file
@@ -0,0 +1,68 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
def add(a: int, b: int) -> int:
|
||||
return a + b
|
||||
|
||||
|
||||
def mul(a: int, b: int) -> int:
|
||||
return a * b
|
||||
|
||||
|
||||
def square(x: int) -> int:
|
||||
return mul(x, x)
|
||||
|
||||
|
||||
def factorial(n: int) -> int:
|
||||
if n <= 1:
|
||||
return 1
|
||||
return n * factorial(n - 1)
|
||||
|
||||
|
||||
def greet(greeting: str, name: str, times: int) -> int:
|
||||
i: int = 0
|
||||
while i < times:
|
||||
stdio.printf("%s, %s!\n", greeting, name)
|
||||
i = i + 1
|
||||
return times
|
||||
|
||||
|
||||
def sub(a: int, b: int) -> int:
|
||||
return a - b
|
||||
|
||||
|
||||
def func_test() -> int:
|
||||
r1: int = add(3, 4)
|
||||
stdio.printf("add(3,4)=%d\n", r1)
|
||||
|
||||
r2: int = mul(5, 6)
|
||||
stdio.printf("mul(5,6)=%d\n", r2)
|
||||
|
||||
r3: int = square(7)
|
||||
stdio.printf("square(7)=%d\n", r3)
|
||||
|
||||
r5: int = factorial(5)
|
||||
stdio.printf("factorial(5)=%d\n", r5)
|
||||
|
||||
# ============================================================
|
||||
# 测试: 函数乱序传参(关键字参数)
|
||||
# ============================================================
|
||||
# 乱序传参:b=4, a=3 等价于 add(3, 4)
|
||||
r6: int = add(b=4, a=3)
|
||||
stdio.printf("add(b=4,a=3)=%d\n", r6)
|
||||
|
||||
# 乱序传参:a=10, b=3 等价于 sub(10, 3)
|
||||
r7: int = sub(b=3, a=10)
|
||||
stdio.printf("sub(b=3,a=10)=%d\n", r7)
|
||||
|
||||
# 混合传参:位置参数 + 关键字参数
|
||||
# greeting="Hello" 是位置参数,name="World" 和 times=2 是关键字
|
||||
r8: int = greet("Hello", name="World", times=2)
|
||||
stdio.printf("greet mixed: returned=%d\n", r8)
|
||||
|
||||
# 全关键字乱序传参
|
||||
r9: int = greet(times=1, name="TransPyC", greeting="Hi")
|
||||
stdio.printf("greet kwargs: returned=%d\n", r9)
|
||||
|
||||
return 0
|
||||
116
Test/App/func_vtable_test.py
Normal file
116
Test/App/func_vtable_test.py
Normal file
@@ -0,0 +1,116 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 场景 A: @t.NoVTable 类 + 函数级 @t.CVTable
|
||||
#
|
||||
# NoVTableClass 标记 @t.NoVTable(类级别禁用虚表)
|
||||
# 但 VirtualMethod 标记 @t.CVTable → 该方法单独进入虚表
|
||||
# NormalMethod 无装饰器 → 不进入虚表
|
||||
# 预期: 虚表 1 个方法 (VirtualMethod)
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class NoVTableClass:
|
||||
val: t.CInt
|
||||
|
||||
def __init__(self, v: t.CInt):
|
||||
self.val = v
|
||||
|
||||
@t.CVTable
|
||||
def VirtualMethod(self) -> t.CInt:
|
||||
return self.val + 10
|
||||
|
||||
def NormalMethod(self) -> t.CInt:
|
||||
return self.val + 20
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 场景 B: @t.CVTable 类 + 函数级 @t.NoVTable
|
||||
#
|
||||
# CVTableClass 标记 @t.CVTable(所有方法进入虚表)
|
||||
# KeptMethod 无装饰器 → 进入虚表
|
||||
# ExcludedMethod 标记 @t.NoVTable → 排除出虚表
|
||||
# 预期: 虚表 1 个方法 (KeptMethod)
|
||||
# ============================================================
|
||||
@t.CVTable
|
||||
class CVTableClass:
|
||||
val: t.CInt
|
||||
|
||||
def __init__(self, v: t.CInt):
|
||||
self.val = v
|
||||
|
||||
def KeptMethod(self) -> t.CInt:
|
||||
return self.val + 30
|
||||
|
||||
@t.NoVTable
|
||||
def ExcludedMethod(self) -> t.CInt:
|
||||
return self.val + 40
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 场景 C: 默认类(无装饰器无继承)+ 函数级 @t.CVTable
|
||||
#
|
||||
# DefaultClass 无装饰器(默认无虚表)
|
||||
# VirtualMethod 标记 @t.CVTable → 单独进入虚表
|
||||
# NormalMethod 无装饰器 → 不进入虚表
|
||||
# 预期: 虚表 1 个方法 (VirtualMethod)
|
||||
# ============================================================
|
||||
class DefaultClass:
|
||||
val: t.CInt
|
||||
|
||||
def __init__(self, v: t.CInt):
|
||||
self.val = v
|
||||
|
||||
@t.CVTable
|
||||
def VirtualMethod(self) -> t.CInt:
|
||||
return self.val + 50
|
||||
|
||||
def NormalMethod(self) -> t.CInt:
|
||||
return self.val + 60
|
||||
|
||||
|
||||
def func_vtable_test() -> int:
|
||||
stdio.printf("funcvt: === Test Start ===\n")
|
||||
|
||||
# 场景 A: NoVTableClass
|
||||
nvt: NoVTableClass = NoVTableClass(5)
|
||||
a1: int = nvt.VirtualMethod()
|
||||
stdio.printf("funcvt: A.VirtualMethod()=%d (expected 15)\n", a1)
|
||||
if a1 != 15:
|
||||
stdio.printf("[FAIL] A.VirtualMethod()=%d expected 15\n", a1)
|
||||
return 1
|
||||
a2: int = nvt.NormalMethod()
|
||||
stdio.printf("funcvt: A.NormalMethod()=%d (expected 25)\n", a2)
|
||||
if a2 != 25:
|
||||
stdio.printf("[FAIL] A.NormalMethod()=%d expected 25\n", a2)
|
||||
return 1
|
||||
|
||||
# 场景 B: CVTableClass
|
||||
cvt: CVTableClass = CVTableClass(7)
|
||||
b1: int = cvt.KeptMethod()
|
||||
stdio.printf("funcvt: B.KeptMethod()=%d (expected 37)\n", b1)
|
||||
if b1 != 37:
|
||||
stdio.printf("[FAIL] B.KeptMethod()=%d expected 37\n", b1)
|
||||
return 1
|
||||
b2: int = cvt.ExcludedMethod()
|
||||
stdio.printf("funcvt: B.ExcludedMethod()=%d (expected 47)\n", b2)
|
||||
if b2 != 47:
|
||||
stdio.printf("[FAIL] B.ExcludedMethod()=%d expected 47\n", b2)
|
||||
return 1
|
||||
|
||||
# 场景 C: DefaultClass
|
||||
dfc: DefaultClass = DefaultClass(9)
|
||||
c1: int = dfc.VirtualMethod()
|
||||
stdio.printf("funcvt: C.VirtualMethod()=%d (expected 59)\n", c1)
|
||||
if c1 != 59:
|
||||
stdio.printf("[FAIL] C.VirtualMethod()=%d expected 59\n", c1)
|
||||
return 1
|
||||
c2: int = dfc.NormalMethod()
|
||||
stdio.printf("funcvt: C.NormalMethod()=%d (expected 69)\n", c2)
|
||||
if c2 != 69:
|
||||
stdio.printf("[FAIL] C.NormalMethod()=%d expected 69\n", c2)
|
||||
return 1
|
||||
|
||||
stdio.printf("funcvt: === All Tests Passed ===\n")
|
||||
return 0
|
||||
102
Test/App/generic_test.py
Normal file
102
Test/App/generic_test.py
Normal file
@@ -0,0 +1,102 @@
|
||||
import stdio
|
||||
import stdlib
|
||||
import t, c
|
||||
import testcheck
|
||||
import memhub
|
||||
import _list
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 泛型类 list[T] 测试
|
||||
# ============================================================
|
||||
def generic_test() -> int:
|
||||
testcheck.begin("GenericTest: list[T] 泛型类测试")
|
||||
|
||||
# 创建 mbuddy arena
|
||||
arena: bytes = stdlib.malloc(65536)
|
||||
bd: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, 65536)
|
||||
|
||||
# === Test 1: 创建和 append ===
|
||||
testcheck.section("Test 1: 创建和 append")
|
||||
nums = list[int](bd)
|
||||
nums.append(10)
|
||||
nums.append(20)
|
||||
nums.append(30)
|
||||
v0: t.CInt = nums.get(0)
|
||||
v1: t.CInt = nums.get(1)
|
||||
v2: t.CInt = nums.get(2)
|
||||
stdio.printf("v0=%d v1=%d v2=%d\n", v0, v1, v2)
|
||||
testcheck.check(v0 == 10 and v1 == 20 and v2 == 30,
|
||||
"append+get OK (10,20,30)", "append+get FAILED")
|
||||
|
||||
# === Test 2: __len__ ===
|
||||
testcheck.section("Test 2: __len__")
|
||||
n: t.CSizeT = nums.__len__()
|
||||
stdio.printf("len=%lu\n", n)
|
||||
testcheck.check(n == 3, "__len__ OK (3)", "__len__ FAILED expect 3")
|
||||
|
||||
# === Test 3: set ===
|
||||
testcheck.section("Test 3: set")
|
||||
nums.set(1, 99)
|
||||
v1b: t.CInt = nums.get(1)
|
||||
stdio.printf("after set(1,99): v1=%d\n", v1b)
|
||||
testcheck.check(v1b == 99, "set OK (idx1=99)", "set FAILED")
|
||||
|
||||
# === Test 4: pop ===
|
||||
testcheck.section("Test 4: pop")
|
||||
popped: t.CInt = nums.pop()
|
||||
stdio.printf("popped=%d\n", popped)
|
||||
testcheck.check(popped == 30, "pop OK (30)", "pop FAILED expect 30")
|
||||
n2: t.CSizeT = nums.__len__()
|
||||
testcheck.check(n2 == 2, "pop len OK (2)", "pop len FAILED expect 2")
|
||||
|
||||
# === Test 5: clear ===
|
||||
testcheck.section("Test 5: clear")
|
||||
nums.clear()
|
||||
n3: t.CSizeT = nums.__len__()
|
||||
testcheck.check(n3 == 0, "clear OK (0)", "clear FAILED expect 0")
|
||||
|
||||
# === Test 6: 容量增长 (append 超过初始容量 8) ===
|
||||
testcheck.section("Test 6: 容量增长")
|
||||
nums2 = list[int](bd)
|
||||
i: t.CInt
|
||||
for i in range(20):
|
||||
nums2.append(i * 5)
|
||||
n4: t.CSizeT = nums2.__len__()
|
||||
stdio.printf("after 20 appends: len=%lu\n", n4)
|
||||
testcheck.check(n4 == 20, "grow len OK (20)", "grow len FAILED")
|
||||
ok: t.CInt = 1
|
||||
for i in range(20):
|
||||
v: t.CInt = nums2.get(i)
|
||||
if v != i * 5:
|
||||
stdio.printf("MISMATCH at %d: got %d expect %d\n", i, v, i * 5)
|
||||
ok = 0
|
||||
break
|
||||
testcheck.check(ok == 1, "grow data OK", "grow data FAILED")
|
||||
|
||||
# === Test 7: 多个 list[int] 实例独立 ===
|
||||
testcheck.section("Test 7: 多实例独立")
|
||||
lst_a = list[int](bd)
|
||||
lst_b = list[int](bd)
|
||||
lst_a.append(111)
|
||||
lst_b.append(222)
|
||||
va: t.CInt = lst_a.get(0)
|
||||
vb: t.CInt = lst_b.get(0)
|
||||
stdio.printf("lst_a[0]=%d lst_b[0]=%d\n", va, vb)
|
||||
testcheck.check(va == 111 and vb == 222,
|
||||
"multi-instance OK (111,222)", "multi-instance FAILED")
|
||||
|
||||
# === Test 8: __getitem__ / __setitem__ ===
|
||||
testcheck.section("Test 8: __getitem__/__setitem__")
|
||||
nums3 = list[int](bd)
|
||||
nums3.append(1)
|
||||
nums3.append(2)
|
||||
nums3.append(3)
|
||||
nums3[0] = 100
|
||||
gv: t.CInt = nums3[0]
|
||||
stdio.printf("nums3[0]=%d after setitem\n", gv)
|
||||
testcheck.check(gv == 100, "__setitem__/__getitem__ OK",
|
||||
"__setitem__/__getitem__ FAILED")
|
||||
|
||||
stdlib.free(arena)
|
||||
return testcheck.end()
|
||||
121
Test/App/inherit_test.py
Normal file
121
Test/App/inherit_test.py
Normal file
@@ -0,0 +1,121 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 继承测试:字段展平 + vtable 继承 + 方法覆盖
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 基类 Animal(有虚方法)
|
||||
# ============================================================
|
||||
@t.CVTable
|
||||
class Animal:
|
||||
name: t.CInt
|
||||
|
||||
def __init__(self, n: t.CInt):
|
||||
self.name = n
|
||||
|
||||
def GetName(self) -> t.CInt:
|
||||
return self.name
|
||||
|
||||
def Speak(self) -> t.CInt:
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 子类 Dog(继承 Animal,覆盖 Speak,新增字段和方法)
|
||||
# ============================================================
|
||||
class Dog(Animal):
|
||||
breed: t.CInt
|
||||
|
||||
def __init__(self, n: t.CInt, b: t.CInt):
|
||||
self.name = n
|
||||
self.breed = b
|
||||
|
||||
def Speak(self) -> t.CInt:
|
||||
return 1
|
||||
|
||||
def GetBreed(self) -> t.CInt:
|
||||
return self.breed
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 子类 Cat(继承 Animal,不覆盖 Speak,新增字段和方法)
|
||||
# ============================================================
|
||||
class Cat(Animal):
|
||||
color: t.CInt
|
||||
|
||||
def __init__(self, n: t.CInt, col: t.CInt):
|
||||
self.name = n
|
||||
self.color = col
|
||||
|
||||
def GetColor(self) -> t.CInt:
|
||||
return self.color
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 主函数
|
||||
# ============================================================
|
||||
def inherit_test() -> int:
|
||||
# ============================================================
|
||||
# 测试 1: 基类 Animal
|
||||
# ============================================================
|
||||
stdio.printf("inherit: === Test 1: Base Class ===\n")
|
||||
a: Animal = Animal(42)
|
||||
aname: int = a.GetName()
|
||||
stdio.printf("inherit: a.GetName()=%d (expected 42)\n", aname)
|
||||
if aname != 42:
|
||||
stdio.printf("[FAIL] a.GetName()=%d expected 42\n", aname)
|
||||
return 1
|
||||
aspeak: int = a.Speak()
|
||||
stdio.printf("inherit: a.Speak()=%d (expected 0)\n", aspeak)
|
||||
if aspeak != 0:
|
||||
stdio.printf("[FAIL] a.Speak()=%d expected 0\n", aspeak)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# 测试 2: 子类 Dog(覆盖 Speak,继承 GetName)
|
||||
# ============================================================
|
||||
stdio.printf("inherit: === Test 2: Dog (override Speak) ===\n")
|
||||
d: Dog = Dog(100, 7)
|
||||
dname: int = d.GetName()
|
||||
stdio.printf("inherit: d.GetName()=%d (expected 100)\n", dname)
|
||||
if dname != 100:
|
||||
stdio.printf("[FAIL] d.GetName()=%d expected 100\n", dname)
|
||||
return 1
|
||||
dspeak: int = d.Speak()
|
||||
stdio.printf("inherit: d.Speak()=%d (expected 1)\n", dspeak)
|
||||
if dspeak != 1:
|
||||
stdio.printf("[FAIL] d.Speak()=%d expected 1\n", dspeak)
|
||||
return 1
|
||||
dbreed: int = d.GetBreed()
|
||||
stdio.printf("inherit: d.GetBreed()=%d (expected 7)\n", dbreed)
|
||||
if dbreed != 7:
|
||||
stdio.printf("[FAIL] d.GetBreed()=%d expected 7\n", dbreed)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# 测试 3: 子类 Cat(不覆盖 Speak,继承 GetName)
|
||||
# ============================================================
|
||||
stdio.printf("inherit: === Test 3: Cat (inherit Speak) ===\n")
|
||||
ct: Cat = Cat(200, 3)
|
||||
cname: int = ct.GetName()
|
||||
stdio.printf("inherit: ct.GetName()=%d (expected 200)\n", cname)
|
||||
if cname != 200:
|
||||
stdio.printf("[FAIL] ct.GetName()=%d expected 200\n", cname)
|
||||
return 1
|
||||
cspeak: int = ct.Speak()
|
||||
stdio.printf("inherit: ct.Speak()=%d (expected 0)\n", cspeak)
|
||||
if cspeak != 0:
|
||||
stdio.printf("[FAIL] ct.Speak()=%d expected 0\n", cspeak)
|
||||
return 1
|
||||
ccolor: int = ct.GetColor()
|
||||
stdio.printf("inherit: ct.GetColor()=%d (expected 3)\n", ccolor)
|
||||
if ccolor != 3:
|
||||
stdio.printf("[FAIL] ct.GetColor()=%d expected 3\n", ccolor)
|
||||
return 1
|
||||
|
||||
stdio.printf("inherit: === All Tests Passed ===\n")
|
||||
return 0
|
||||
247
Test/App/llvmir_test.py
Normal file
247
Test/App/llvmir_test.py
Normal file
@@ -0,0 +1,247 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
import stdio
|
||||
|
||||
|
||||
# ============================================================
|
||||
# c.LLVMIR / c.LInp / c.LOut 内联 LLVM IR 测试
|
||||
#
|
||||
# 测试 c.LLVMIR 内联 LLVM IR 指令的生成和执行
|
||||
# - c.LInp(expr) 标记输入操作数
|
||||
# - c.LOut(expr) 标记输出操作数
|
||||
# ============================================================
|
||||
|
||||
|
||||
# Test 1: 基本加法 add
|
||||
def test_add() -> t.CInt:
|
||||
stdio.printf("--- Test 1: LLVMIR add ---\n")
|
||||
a: t.CInt = 10
|
||||
b: t.CInt = 20
|
||||
r: t.CInt = c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("add(10, 20)=%d (expect 30)\n", r)
|
||||
if r == 30:
|
||||
stdio.printf("LLVMIR add OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR add FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 2: 基本减法 sub
|
||||
def test_sub() -> t.CInt:
|
||||
stdio.printf("--- Test 2: LLVMIR sub ---\n")
|
||||
a: t.CInt = 50
|
||||
b: t.CInt = 20
|
||||
r: t.CInt = c.LLVMIR(f"sub i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("sub(50, 20)=%d (expect 30)\n", r)
|
||||
if r == 30:
|
||||
stdio.printf("LLVMIR sub OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR sub FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 3: 基本乘法 mul
|
||||
def test_mul() -> t.CInt:
|
||||
stdio.printf("--- Test 3: LLVMIR mul ---\n")
|
||||
a: t.CInt = 6
|
||||
b: t.CInt = 7
|
||||
r: t.CInt = c.LLVMIR(f"mul i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("mul(6, 7)=%d (expect 42)\n", r)
|
||||
if r == 42:
|
||||
stdio.printf("LLVMIR mul OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR mul FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 4: 基本除法 sdiv
|
||||
def test_sdiv() -> t.CInt:
|
||||
stdio.printf("--- Test 4: LLVMIR sdiv ---\n")
|
||||
a: t.CInt = 100
|
||||
b: t.CInt = 4
|
||||
r: t.CInt = c.LLVMIR(f"sdiv i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("sdiv(100, 4)=%d (expect 25)\n", r)
|
||||
if r == 25:
|
||||
stdio.printf("LLVMIR sdiv OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR sdiv FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 5: 位运算 and
|
||||
def test_and() -> t.CInt:
|
||||
stdio.printf("--- Test 5: LLVMIR and ---\n")
|
||||
a: t.CInt = 255
|
||||
b: t.CInt = 15
|
||||
r: t.CInt = c.LLVMIR(f"and i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("and(255, 15)=%d (expect 15)\n", r)
|
||||
if r == 15:
|
||||
stdio.printf("LLVMIR and OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR and FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 6: 位运算 or
|
||||
def test_or() -> t.CInt:
|
||||
stdio.printf("--- Test 6: LLVMIR or ---\n")
|
||||
a: t.CInt = 240
|
||||
b: t.CInt = 15
|
||||
r: t.CInt = c.LLVMIR(f"or i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("or(240, 15)=%d (expect 255)\n", r)
|
||||
if r == 255:
|
||||
stdio.printf("LLVMIR or OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR or FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 7: 位运算 xor
|
||||
def test_xor() -> t.CInt:
|
||||
stdio.printf("--- Test 7: LLVMIR xor ---\n")
|
||||
a: t.CInt = 255
|
||||
b: t.CInt = 15
|
||||
r: t.CInt = c.LLVMIR(f"xor i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("xor(255, 15)=%d (expect 240)\n", r)
|
||||
if r == 240:
|
||||
stdio.printf("LLVMIR xor OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR xor FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 8: 左移 shl
|
||||
def test_shl() -> t.CInt:
|
||||
stdio.printf("--- Test 8: LLVMIR shl ---\n")
|
||||
a: t.CInt = 1
|
||||
b: t.CInt = 4
|
||||
r: t.CInt = c.LLVMIR(f"shl i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("shl(1, 4)=%d (expect 16)\n", r)
|
||||
if r == 16:
|
||||
stdio.printf("LLVMIR shl OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR shl FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 9: LOut 输出赋值
|
||||
def test_lout() -> t.CInt:
|
||||
stdio.printf("--- Test 9: LLVMIR LOut ---\n")
|
||||
a: t.CInt = 10
|
||||
b: t.CInt = 20
|
||||
out_val: t.CInt = 0
|
||||
c.LLVMIR(f"{c.LOut(out_val)} = add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("LOut add(10, 20)=%d (expect 30)\n", out_val)
|
||||
if out_val == 30:
|
||||
stdio.printf("LLVMIR LOut OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR LOut FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 10: icmp eq 比较
|
||||
# 注意: TransPyV 用 sext i1 to i32 扩展布尔结果,true -> -1
|
||||
def test_icmp_eq() -> t.CInt:
|
||||
stdio.printf("--- Test 10: LLVMIR icmp eq ---\n")
|
||||
a: t.CInt = 5
|
||||
b: t.CInt = 5
|
||||
r: t.CInt = c.LLVMIR(f"icmp eq i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("icmp eq(5, 5)=%d (expect nonzero)\n", r)
|
||||
if r != 0:
|
||||
stdio.printf("LLVMIR icmp eq OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR icmp eq FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 11: icmp ne 比较
|
||||
def test_icmp_ne() -> t.CInt:
|
||||
stdio.printf("--- Test 11: LLVMIR icmp ne ---\n")
|
||||
a: t.CInt = 5
|
||||
b: t.CInt = 3
|
||||
r: t.CInt = c.LLVMIR(f"icmp ne i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("icmp ne(5, 3)=%d (expect nonzero)\n", r)
|
||||
if r != 0:
|
||||
stdio.printf("LLVMIR icmp ne OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR icmp ne FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 12: icmp slt 比较
|
||||
def test_icmp_slt() -> t.CInt:
|
||||
stdio.printf("--- Test 12: LLVMIR icmp slt ---\n")
|
||||
a: t.CInt = 3
|
||||
b: t.CInt = 5
|
||||
r: t.CInt = c.LLVMIR(f"icmp slt i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("icmp slt(3, 5)=%d (expect nonzero)\n", r)
|
||||
if r != 0:
|
||||
stdio.printf("LLVMIR icmp slt OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR icmp slt FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 13: srem 取余
|
||||
def test_srem() -> t.CInt:
|
||||
stdio.printf("--- Test 13: LLVMIR srem ---\n")
|
||||
a: t.CInt = 17
|
||||
b: t.CInt = 5
|
||||
r: t.CInt = c.LLVMIR(f"srem i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("srem(17, 5)=%d (expect 2)\n", r)
|
||||
if r == 2:
|
||||
stdio.printf("LLVMIR srem OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR srem FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 14: lshr 逻辑右移
|
||||
def test_lshr() -> t.CInt:
|
||||
stdio.printf("--- Test 14: LLVMIR lshr ---\n")
|
||||
a: t.CInt = 256
|
||||
b: t.CInt = 2
|
||||
r: t.CInt = c.LLVMIR(f"lshr i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
stdio.printf("lshr(256, 2)=%d (expect 64)\n", r)
|
||||
if r == 64:
|
||||
stdio.printf("LLVMIR lshr OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR lshr FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
# Test 15: 嵌套在表达式中使用
|
||||
def test_nested() -> t.CInt:
|
||||
stdio.printf("--- Test 15: LLVMIR nested in expression ---\n")
|
||||
a: t.CInt = 10
|
||||
b: t.CInt = 20
|
||||
# c.LLVMIR 结果参与后续运算
|
||||
llvmir_result: t.CInt = c.LLVMIR(f"add i32 {c.LInp(a)}, {c.LInp(b)}", t.CInt)
|
||||
final_result: t.CInt = llvmir_result + 10
|
||||
stdio.printf("(LLVMIR add(10,20)) + 10 = %d (expect 40)\n", final_result)
|
||||
if final_result == 40:
|
||||
stdio.printf("LLVMIR nested OK\n")
|
||||
else:
|
||||
stdio.printf("LLVMIR nested FAIL\n")
|
||||
return 0
|
||||
|
||||
|
||||
def llvmir_test() -> t.CInt:
|
||||
stdio.printf("=== llvmir_test: c.LLVMIR 内联 LLVM IR 测试 ===\n\n")
|
||||
test_add()
|
||||
test_sub()
|
||||
test_mul()
|
||||
test_sdiv()
|
||||
test_and()
|
||||
test_or()
|
||||
test_xor()
|
||||
test_shl()
|
||||
test_lout()
|
||||
test_icmp_eq()
|
||||
test_icmp_ne()
|
||||
test_icmp_slt()
|
||||
test_srem()
|
||||
test_lshr()
|
||||
test_nested()
|
||||
stdio.printf("\n=== llvmir_test 完成 ===\n")
|
||||
return 0
|
||||
60
Test/App/namespace_defs.py
Normal file
60
Test/App/namespace_defs.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 命名空间隔离测试:定义类模块
|
||||
#
|
||||
# 本文件定义供其他文件 import 使用的类,验证跨模块命名空间隔离:
|
||||
# - 裸名 Class(): 需要 from namespace_defs import Class
|
||||
# - 模块限定 namespace_defs.Class(): 需要 import namespace_defs
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 带虚表的类 Widget
|
||||
# ============================================================
|
||||
@t.CVTable
|
||||
class Widget:
|
||||
id: t.CInt
|
||||
|
||||
def __init__(self, i: t.CInt):
|
||||
self.id = i
|
||||
|
||||
def GetId(self) -> t.CInt:
|
||||
return self.id
|
||||
|
||||
def Render(self) -> t.CInt:
|
||||
return 100
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 子类 Gadget(继承 Widget,覆盖 Render)
|
||||
# ============================================================
|
||||
class Gadget(Widget):
|
||||
extra: t.CInt
|
||||
|
||||
def __init__(self, i: t.CInt, e: t.CInt):
|
||||
self.id = i
|
||||
self.extra = e
|
||||
|
||||
def Render(self) -> t.CInt:
|
||||
return 200
|
||||
|
||||
def GetExtra(self) -> t.CInt:
|
||||
return self.extra
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 普通结构体 PlainStruct(无虚表)
|
||||
# ============================================================
|
||||
class PlainStruct:
|
||||
x: t.CInt
|
||||
y: t.CInt
|
||||
|
||||
def __init__(self, ax: t.CInt, ay: t.CInt):
|
||||
self.x = ax
|
||||
self.y = ay
|
||||
|
||||
def Sum(self) -> t.CInt:
|
||||
return self.x + self.y
|
||||
111
Test/App/namespace_test.py
Normal file
111
Test/App/namespace_test.py
Normal file
@@ -0,0 +1,111 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import namespace_defs
|
||||
from namespace_defs import Widget, Gadget, PlainStruct
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 命名空间隔离测试
|
||||
#
|
||||
# 验证跨模块类访问必须通过 import:
|
||||
# - Test 1: from X import Class → 裸名 Class() 构造
|
||||
# - Test 2: import X → 模块限定 X.Class() 构造
|
||||
# - Test 3: 类型注解使用导入的类
|
||||
# - Test 4: 继承类的虚分派(跨模块继承)
|
||||
# ============================================================
|
||||
|
||||
|
||||
def namespace_test() -> int:
|
||||
stdio.printf("nsisol: === Test Start ===\n")
|
||||
|
||||
# ============================================================
|
||||
# Test 1: from X import Class → 裸名 Class() 构造
|
||||
# ============================================================
|
||||
stdio.printf("nsisol: === Test 1: from-import bare constructor ===\n")
|
||||
|
||||
w: Widget = Widget(42)
|
||||
wid: int = w.GetId()
|
||||
stdio.printf("nsisol: w.GetId()=%d (expected 42)\n", wid)
|
||||
if wid != 42:
|
||||
stdio.printf("[FAIL] w.GetId()=%d expected 42\n", wid)
|
||||
return 1
|
||||
|
||||
wrender: int = w.Render()
|
||||
stdio.printf("nsisol: w.Render()=%d (expected 100)\n", wrender)
|
||||
if wrender != 100:
|
||||
stdio.printf("[FAIL] w.Render()=%d expected 100\n", wrender)
|
||||
return 1
|
||||
|
||||
g: Gadget = Gadget(7, 9)
|
||||
grender: int = g.Render()
|
||||
stdio.printf("nsisol: g.Render()=%d (expected 200)\n", grender)
|
||||
if grender != 200:
|
||||
stdio.printf("[FAIL] g.Render()=%d expected 200\n", grender)
|
||||
return 1
|
||||
|
||||
gextra: int = g.GetExtra()
|
||||
stdio.printf("nsisol: g.GetExtra()=%d (expected 9)\n", gextra)
|
||||
if gextra != 9:
|
||||
stdio.printf("[FAIL] g.GetExtra()=%d expected 9\n", gextra)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# Test 2: import X → 模块限定 X.Class() 构造
|
||||
# ============================================================
|
||||
stdio.printf("nsisol: === Test 2: module-qualified constructor ===\n")
|
||||
|
||||
ps: PlainStruct = PlainStruct(10, 20)
|
||||
psum: int = ps.Sum()
|
||||
stdio.printf("nsisol: ps.Sum()=%d (expected 30)\n", psum)
|
||||
if psum != 30:
|
||||
stdio.printf("[FAIL] ps.Sum()=%d expected 30\n", psum)
|
||||
return 1
|
||||
|
||||
ps2: namespace_defs.PlainStruct = namespace_defs.PlainStruct(5, 6)
|
||||
psum2: int = ps2.Sum()
|
||||
stdio.printf("nsisol: ps2.Sum()=%d (expected 11)\n", psum2)
|
||||
if psum2 != 11:
|
||||
stdio.printf("[FAIL] ps2.Sum()=%d expected 11\n", psum2)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# Test 3: 类型注解使用导入的类
|
||||
# ============================================================
|
||||
stdio.printf("nsisol: === Test 3: type annotation with imported class ===\n")
|
||||
|
||||
annot_w: Widget = Widget(99)
|
||||
annot_id: int = annot_w.GetId()
|
||||
stdio.printf("nsisol: annot_w.GetId()=%d (expected 99)\n", annot_id)
|
||||
if annot_id != 99:
|
||||
stdio.printf("[FAIL] annot_w.GetId()=%d expected 99\n", annot_id)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# Test 4: 跨模块继承的虚分派
|
||||
# ============================================================
|
||||
stdio.printf("nsisol: === Test 4: cross-module inheritance vtable ===\n")
|
||||
|
||||
# Gadget 继承 Widget,覆盖 Render
|
||||
# Widget.Render()=100, Gadget.Render()=200
|
||||
base: Widget = Widget(1)
|
||||
derived: Gadget = Gadget(2, 3)
|
||||
base_r: int = base.Render()
|
||||
deriv_r: int = derived.Render()
|
||||
stdio.printf("nsisol: base.Render()=%d (expected 100)\n", base_r)
|
||||
if base_r != 100:
|
||||
stdio.printf("[FAIL] base.Render()=%d expected 100\n", base_r)
|
||||
return 1
|
||||
stdio.printf("nsisol: derived.Render()=%d (expected 200)\n", deriv_r)
|
||||
if deriv_r != 200:
|
||||
stdio.printf("[FAIL] derived.Render()=%d expected 200\n", deriv_r)
|
||||
return 1
|
||||
|
||||
# 继承的方法:Gadget 继承 Widget.GetId
|
||||
gname: int = derived.GetId()
|
||||
stdio.printf("nsisol: derived.GetId()=%d (expected 2)\n", gname)
|
||||
if gname != 2:
|
||||
stdio.printf("[FAIL] derived.GetId()=%d expected 2\n", gname)
|
||||
return 1
|
||||
|
||||
stdio.printf("nsisol: === All Tests Passed ===\n")
|
||||
return 0
|
||||
119
Test/App/new_test.py
Normal file
119
Test/App/new_test.py
Normal file
@@ -0,0 +1,119 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# __new__ 函数测试:验证 __new__ 在创建 OOP 结构体前被调用,
|
||||
# 返回的指针作为结构体存储空间。
|
||||
#
|
||||
# __new__ 签名默认和 __init__ 一样(self + args),返回 Ptr(struct_ty)。
|
||||
# 如果 __new__ 返回 self,则使用默认 alloca 作为存储空间。
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Test 1: __new__ 返回 self(默认 alloca)
|
||||
# 验证 __new__ 被调用且不破坏 __init__ 正常功能
|
||||
# ============================================================
|
||||
class WithNew:
|
||||
value: t.CInt
|
||||
|
||||
def __new__(self, v: t.CInt):
|
||||
stdio.printf("new: WithNew.__new__ called\n")
|
||||
return self
|
||||
|
||||
def __init__(self, v: t.CInt):
|
||||
stdio.printf("new: WithNew.__init__ called\n")
|
||||
self.value = v
|
||||
|
||||
def GetValue(self) -> t.CInt:
|
||||
return self.value
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Test 2: __new__ 不接受额外参数(仅 self)
|
||||
# 验证 __new__ 签名可以与 __init__ 不同
|
||||
# ============================================================
|
||||
class WithNewNoArgs:
|
||||
value: t.CInt
|
||||
|
||||
def __new__(self):
|
||||
stdio.printf("new: WithNewNoArgs.__new__ called\n")
|
||||
return self
|
||||
|
||||
def __init__(self, v: t.CInt):
|
||||
self.value = v
|
||||
|
||||
def GetValue(self) -> t.CInt:
|
||||
return self.value
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Test 3: __new__ + @t.CVTable 虚表类
|
||||
# 验证 __new__ 与虚表机制兼容(__new__ 不进入虚表)
|
||||
# ============================================================
|
||||
@t.CVTable
|
||||
class WithNewVTable:
|
||||
value: t.CInt
|
||||
|
||||
def __new__(self, v: t.CInt):
|
||||
stdio.printf("new: WithNewVTable.__new__ called\n")
|
||||
return self
|
||||
|
||||
def __init__(self, v: t.CInt):
|
||||
self.value = v
|
||||
|
||||
def GetValue(self) -> t.CInt:
|
||||
return self.value
|
||||
|
||||
def Speak(self) -> t.CInt:
|
||||
return self.value + 1
|
||||
|
||||
|
||||
def new_test() -> int:
|
||||
stdio.printf("new: === Test Start ===\n")
|
||||
|
||||
# ============================================================
|
||||
# Test 1: __new__ 返回 self
|
||||
# ============================================================
|
||||
stdio.printf("new: === Test 1: __new__ returns self ===\n")
|
||||
|
||||
w: WithNew = WithNew(42)
|
||||
v: int = w.GetValue()
|
||||
stdio.printf("new: w.GetValue()=%d (expected 42)\n", v)
|
||||
if v != 42:
|
||||
stdio.printf("[FAIL] w.GetValue()=%d expected 42\n", v)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# Test 2: __new__ 不接受额外参数
|
||||
# ============================================================
|
||||
stdio.printf("new: === Test 2: __new__ no extra args ===\n")
|
||||
|
||||
n: WithNewNoArgs = WithNewNoArgs(99)
|
||||
nv: int = n.GetValue()
|
||||
stdio.printf("new: n.GetValue()=%d (expected 99)\n", nv)
|
||||
if nv != 99:
|
||||
stdio.printf("[FAIL] n.GetValue()=%d expected 99\n", nv)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# Test 3: __new__ + 虚表类
|
||||
# ============================================================
|
||||
stdio.printf("new: === Test 3: __new__ + vtable ===\n")
|
||||
|
||||
vt: WithNewVTable = WithNewVTable(10)
|
||||
vtv: int = vt.GetValue()
|
||||
stdio.printf("new: vt.GetValue()=%d (expected 10)\n", vtv)
|
||||
if vtv != 10:
|
||||
stdio.printf("[FAIL] vt.GetValue()=%d expected 10\n", vtv)
|
||||
return 1
|
||||
|
||||
vts: int = vt.Speak()
|
||||
stdio.printf("new: vt.Speak()=%d (expected 11)\n", vts)
|
||||
if vts != 11:
|
||||
stdio.printf("[FAIL] vt.Speak()=%d expected 11\n", vts)
|
||||
return 1
|
||||
|
||||
stdio.printf("new: === All Tests Passed ===\n")
|
||||
return 0
|
||||
129
Test/App/oop_test.py
Normal file
129
Test/App/oop_test.py
Normal file
@@ -0,0 +1,129 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# OOP 测试:存在方法的 class 自动升级为 OOP 结构体
|
||||
# ============================================================
|
||||
|
||||
# ============================================================
|
||||
# 测试 1: 基本方法(无 __init__,__before_init__ 零值填充)
|
||||
# ============================================================
|
||||
class Point:
|
||||
x: t.CInt
|
||||
y: t.CInt
|
||||
|
||||
def MoveTo(self, nx: t.CInt, ny: t.CInt) -> t.CInt:
|
||||
self.x = nx
|
||||
self.y = ny
|
||||
return 0
|
||||
|
||||
def GetX(self) -> t.CInt:
|
||||
return self.x
|
||||
|
||||
def GetY(self) -> t.CInt:
|
||||
return self.y
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 测试 2: 带默认值的 OOP 结构体(__before_init__ 应用默认值)
|
||||
# ============================================================
|
||||
class Counter:
|
||||
count: t.CInt = 0
|
||||
step: t.CInt = 1
|
||||
|
||||
def Increment(self) -> t.CInt:
|
||||
self.count = self.count + self.step
|
||||
return self.count
|
||||
|
||||
def Reset(self) -> t.CInt:
|
||||
self.count = 0
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 测试 3: __init__ 构造函数
|
||||
# ============================================================
|
||||
class Rect:
|
||||
width: t.CInt
|
||||
height: t.CInt
|
||||
|
||||
def __init__(self, w: t.CInt, h: t.CInt):
|
||||
self.width = w
|
||||
self.height = h
|
||||
|
||||
def Area(self) -> t.CInt:
|
||||
return self.width * self.height
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 主函数
|
||||
# ============================================================
|
||||
def oop_test() -> int:
|
||||
# ============================================================
|
||||
# 测试 1: 基本方法调用
|
||||
# ============================================================
|
||||
stdio.printf("oop: === Test 1: Basic Methods ===\n")
|
||||
p: Point = Point()
|
||||
p.MoveTo(10, 20)
|
||||
stdio.printf("oop: p.x=%d p.y=%d\n", p.GetX(), p.GetY())
|
||||
|
||||
if p.GetX() != 10:
|
||||
stdio.printf("[FAIL] p.GetX()=%d expected 10\n", p.GetX())
|
||||
return 1
|
||||
if p.GetY() != 20:
|
||||
stdio.printf("[FAIL] p.GetY()=%d expected 20\n", p.GetY())
|
||||
return 1
|
||||
|
||||
# 修改字段后再次调用方法
|
||||
p.MoveTo(100, 200)
|
||||
stdio.printf("oop: after move p.x=%d p.y=%d\n", p.GetX(), p.GetY())
|
||||
if p.GetX() != 100:
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# 测试 2: 默认值 + 方法
|
||||
# ============================================================
|
||||
stdio.printf("oop: === Test 2: Defaults + Methods ===\n")
|
||||
cnt: Counter = Counter()
|
||||
stdio.printf("oop: initial count=%d step=%d\n", cnt.count, cnt.step)
|
||||
if cnt.count != 0:
|
||||
stdio.printf("[FAIL] cnt.count=%d expected 0\n", cnt.count)
|
||||
return 1
|
||||
if cnt.step != 1:
|
||||
stdio.printf("[FAIL] cnt.step=%d expected 1\n", cnt.step)
|
||||
return 1
|
||||
|
||||
r1: int = cnt.Increment()
|
||||
r2: int = cnt.Increment()
|
||||
r3: int = cnt.Increment()
|
||||
stdio.printf("oop: after 3 increments: %d %d %d\n", r1, r2, r3)
|
||||
if r1 != 1 or r2 != 2 or r3 != 3:
|
||||
stdio.printf("[FAIL] increments: %d %d %d\n", r1, r2, r3)
|
||||
return 1
|
||||
|
||||
cnt.Reset()
|
||||
r4: int = cnt.Increment()
|
||||
stdio.printf("oop: after reset+increment: %d\n", r4)
|
||||
if r4 != 1:
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# 测试 3: __init__ 构造函数
|
||||
# ============================================================
|
||||
stdio.printf("oop: === Test 3: __init__ ===\n")
|
||||
rect: Rect = Rect(3, 4)
|
||||
area: int = rect.Area()
|
||||
stdio.printf("oop: rect %dx%d area=%d\n", rect.width, rect.height, area)
|
||||
if area != 12:
|
||||
stdio.printf("[FAIL] area=%d expected 12\n", area)
|
||||
return 1
|
||||
if rect.width != 3:
|
||||
stdio.printf("[FAIL] width=%d expected 3\n", rect.width)
|
||||
return 1
|
||||
if rect.height != 4:
|
||||
stdio.printf("[FAIL] height=%d expected 4\n", rect.height)
|
||||
return 1
|
||||
|
||||
stdio.printf("oop: === All OOP Tests Passed ===\n")
|
||||
return 0
|
||||
253
Test/App/opovl_test.py
Normal file
253
Test/App/opovl_test.py
Normal file
@@ -0,0 +1,253 @@
|
||||
import stdio
|
||||
import stdlib
|
||||
import t, c
|
||||
import testcheck
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 运算符重载测试
|
||||
#
|
||||
# 验证: 当 lhs 是结构体指针时,二元/比较运算触发 dunder 方法调用
|
||||
# 支持: __add__/__sub__/__mul__/__div__/__mod__/__and__/__or__/__xor__
|
||||
# __lshift__/__rshift__/__floordiv__ (BinOp)
|
||||
# __eq__/__ne__/__lt__/__le__/__gt__/__ge__ (Compare)
|
||||
#
|
||||
# 三种测试场景:
|
||||
# 1. Counter/BitBox: dunder 返回 t.CInt(值类型变量触发重载)
|
||||
# 2. Vec2: dunder 返回 Vec2|t.CPtr(堆分配结构体,指针类型变量触发重载)
|
||||
# 3. 原生整数运算回退
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Counter: 演示 __add__/__mul__/__sub__ + 比较重载
|
||||
# dunder 返回 t.CInt
|
||||
# ============================================================
|
||||
class Counter:
|
||||
val: t.CInt
|
||||
|
||||
def __init__(self, v: t.CInt):
|
||||
self.val = v
|
||||
|
||||
def __add__(self, n: t.CInt) -> t.CInt:
|
||||
return self.val + n
|
||||
|
||||
def __sub__(self, n: t.CInt) -> t.CInt:
|
||||
return self.val - n
|
||||
|
||||
def __mul__(self, n: t.CInt) -> t.CInt:
|
||||
return self.val * n
|
||||
|
||||
def __div__(self, n: t.CInt) -> t.CInt:
|
||||
return self.val / n
|
||||
|
||||
def __mod__(self, n: t.CInt) -> t.CInt:
|
||||
return self.val % n
|
||||
|
||||
def __eq__(self, n: t.CInt) -> t.CInt:
|
||||
if self.val == n:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def __ne__(self, n: t.CInt) -> t.CInt:
|
||||
if self.val != n:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def __lt__(self, n: t.CInt) -> t.CInt:
|
||||
if self.val < n:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def __le__(self, n: t.CInt) -> t.CInt:
|
||||
if self.val <= n:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def __gt__(self, n: t.CInt) -> t.CInt:
|
||||
if self.val > n:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def __ge__(self, n: t.CInt) -> t.CInt:
|
||||
if self.val >= n:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# BitBox: 演示位运算重载
|
||||
# dunder 返回 t.CInt
|
||||
# ============================================================
|
||||
class BitBox:
|
||||
flags: t.CInt
|
||||
|
||||
def __init__(self, v: t.CInt):
|
||||
self.flags = v
|
||||
|
||||
def __and__(self, mask: t.CInt) -> t.CInt:
|
||||
return self.flags & mask
|
||||
|
||||
def __or__(self, mask: t.CInt) -> t.CInt:
|
||||
return self.flags | mask
|
||||
|
||||
def __xor__(self, mask: t.CInt) -> t.CInt:
|
||||
return self.flags ^ mask
|
||||
|
||||
def __lshift__(self, n: t.CInt) -> t.CInt:
|
||||
return self.flags << n
|
||||
|
||||
def __rshift__(self, n: t.CInt) -> t.CInt:
|
||||
return self.flags >> n
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Vec2: 演示结构体运算重载
|
||||
#
|
||||
# __new__ + stdlib.malloc 在堆上分配内存,使 Vec2|t.CPtr 变量
|
||||
# 能正确工作(dunder 方法返回堆上新对象)。
|
||||
#
|
||||
# __new__ 返回 malloc 的堆指针作为结构体存储空间,
|
||||
# 后续 __init__ 在堆指针上初始化字段。
|
||||
# ============================================================
|
||||
class Vec2:
|
||||
x: t.CInt
|
||||
y: t.CInt
|
||||
|
||||
def __new__(self, x0: t.CInt, y0: t.CInt):
|
||||
r: Vec2 | t.CPtr = stdlib.malloc(Vec2.__sizeof__())
|
||||
return r
|
||||
|
||||
def __init__(self, x0: t.CInt, y0: t.CInt):
|
||||
self.x = x0
|
||||
self.y = y0
|
||||
|
||||
def __add__(self, other: Vec2 | t.CPtr) -> Vec2 | t.CPtr:
|
||||
r: Vec2 | t.CPtr = Vec2(0, 0)
|
||||
r.x = self.x + other.x
|
||||
r.y = self.y + other.y
|
||||
return r
|
||||
|
||||
def __sub__(self, other: Vec2 | t.CPtr) -> Vec2 | t.CPtr:
|
||||
r: Vec2 | t.CPtr = Vec2(0, 0)
|
||||
r.x = self.x - other.x
|
||||
r.y = self.y - other.y
|
||||
return r
|
||||
|
||||
def __eq__(self, other: Vec2 | t.CPtr) -> t.CInt:
|
||||
if self.x == other.x:
|
||||
if self.y == other.y:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def __ne__(self, other: Vec2 | t.CPtr) -> t.CInt:
|
||||
if self.x != other.x:
|
||||
return 1
|
||||
if self.y != other.y:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 主测试入口
|
||||
# ============================================================
|
||||
def opovl_test() -> int:
|
||||
testcheck.begin("Operator Overload Tests")
|
||||
|
||||
# ============================================================
|
||||
# 测试 1: Counter + int 触发 __add__
|
||||
# ============================================================
|
||||
testcheck.section("Counter __add__")
|
||||
cnt: Counter = Counter(10)
|
||||
sum_val: int = cnt + 5
|
||||
testcheck.check(sum_val == 15, "cnt(10)+5=15", "cnt+5 expected 15 got ??")
|
||||
|
||||
# ============================================================
|
||||
# 测试 2: Counter - int / * int / / int / % int
|
||||
# ============================================================
|
||||
testcheck.section("Counter __sub__/__mul__/__div__/__mod__")
|
||||
sub_val: int = cnt - 3
|
||||
mul_val: int = cnt * 3
|
||||
div_val: int = cnt / 3
|
||||
mod_val: int = cnt % 3
|
||||
testcheck.check(sub_val == 7, "cnt-3=7", "cnt-3 expected 7")
|
||||
testcheck.check(mul_val == 30, "cnt*3=30", "cnt*3 expected 30")
|
||||
testcheck.check(div_val == 3, "cnt/3=3", "cnt/3 expected 3")
|
||||
testcheck.check(mod_val == 1, "cnt%3=1", "cnt%3 expected 1")
|
||||
|
||||
# ============================================================
|
||||
# 测试 3: Counter 比较重载 (==, !=, <, <=, >, >=)
|
||||
# ============================================================
|
||||
testcheck.section("Counter compare overloads")
|
||||
eq_10: int = cnt == 10
|
||||
ne_10: int = cnt != 10
|
||||
lt_20: int = cnt < 20
|
||||
le_10: int = cnt <= 10
|
||||
gt_5: int = cnt > 5
|
||||
ge_10: int = cnt >= 10
|
||||
testcheck.check(eq_10 == 1, "cnt==10:1", "cnt==10 expected 1")
|
||||
testcheck.check(ne_10 == 0, "cnt!=10:0", "cnt!=10 expected 0")
|
||||
testcheck.check(lt_20 == 1, "cnt<20:1", "cnt<20 expected 1")
|
||||
testcheck.check(le_10 == 1, "cnt<=10:1", "cnt<=10 expected 1")
|
||||
testcheck.check(gt_5 == 1, "cnt>5:1", "cnt>5 expected 1")
|
||||
testcheck.check(ge_10 == 1, "cnt>=10:1", "cnt>=10 expected 1")
|
||||
|
||||
# ============================================================
|
||||
# 测试 4: BitBox 位运算重载
|
||||
# ============================================================
|
||||
testcheck.section("BitBox bitwise overloads")
|
||||
bb: BitBox = BitBox(0xFF)
|
||||
and_val: int = bb & 0x0F
|
||||
or_val: int = bb | 0x100
|
||||
xor_val: int = bb ^ 0x55
|
||||
lsh_val: int = bb << 4
|
||||
rsh_val: int = bb >> 4
|
||||
testcheck.check(and_val == 0x0F, "bb&0x0F=15", "bb&0x0F expected 15")
|
||||
testcheck.check(or_val == 0x1FF, "bb|0x100=511", "bb|0x100 expected 511")
|
||||
testcheck.check(xor_val == 0xAA, "bb^0x55=170", "bb^0x55 expected 170")
|
||||
testcheck.check(lsh_val == 0xFF0, "bb<<4=4080", "bb<<4 expected 4080")
|
||||
testcheck.check(rsh_val == 0x0F, "bb>>4=15", "bb>>4 expected 15")
|
||||
|
||||
# ============================================================
|
||||
# 测试 5: 原生整数运算不受影响(回退路径)
|
||||
# ============================================================
|
||||
testcheck.section("Native int binop")
|
||||
x: int = 7 + 8
|
||||
y: int = 10 - 3
|
||||
z: int = 4 * 5
|
||||
testcheck.check(x == 15, "7+8=15", "7+8 expected 15")
|
||||
testcheck.check(y == 7, "10-3=7", "10-3 expected 7")
|
||||
testcheck.check(z == 20, "4*5=20", "4*5 expected 20")
|
||||
|
||||
# ============================================================
|
||||
# 测试 6: 原生整数比较不受影响
|
||||
# ============================================================
|
||||
testcheck.section("Native int compare")
|
||||
testcheck.check(3 < 5, "3<5", "3<5 broken")
|
||||
testcheck.check(10 == 10, "10==10", "10==10 broken")
|
||||
|
||||
# ============================================================
|
||||
# 测试 7: Vec2 结构体运算重载
|
||||
# ============================================================
|
||||
testcheck.section("Vec2 struct overloads")
|
||||
a: Vec2 | t.CPtr = Vec2(3, 4)
|
||||
b: Vec2 | t.CPtr = Vec2(1, 2)
|
||||
c: Vec2 | t.CPtr = a + b
|
||||
d: Vec2 | t.CPtr = a - b
|
||||
testcheck.check(c.x == 4, "a+b x=4", "a+b x expected 4")
|
||||
testcheck.check(c.y == 6, "a+b y=6", "a+b y expected 6")
|
||||
testcheck.check(d.x == 2, "a-b x=2", "a-b x expected 2")
|
||||
testcheck.check(d.y == 2, "a-b y=2", "a-b y expected 2")
|
||||
|
||||
# ============================================================
|
||||
# 测试 8: Vec2 比较重载
|
||||
# ============================================================
|
||||
testcheck.section("Vec2 compare overloads")
|
||||
p: Vec2 | t.CPtr = Vec2(5, 5)
|
||||
q: Vec2 | t.CPtr = Vec2(5, 5)
|
||||
eq_v: int = p == q
|
||||
ne_v: int = p != q
|
||||
testcheck.check(eq_v == 1, "(5,5)==(5,5):1", "p==q expected 1")
|
||||
testcheck.check(ne_v == 0, "(5,5)!=(5,5):0", "p!=q expected 0")
|
||||
|
||||
return testcheck.end()
|
||||
26
Test/App/ptr_only_test.py
Normal file
26
Test/App/ptr_only_test.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
def ptr_only_test() -> int:
|
||||
s: str = "hello"
|
||||
sp: str = s
|
||||
slen: int = 0
|
||||
while c.Deref(sp) != 0:
|
||||
slen = slen + 1
|
||||
sp = sp + 1
|
||||
stdio.printf("ptr: len(hello)=%d\n", slen)
|
||||
|
||||
x: int = 65
|
||||
px: str = c.Addr(x)
|
||||
c.DerefAs(px, 88)
|
||||
stdio.printf("ptr: after DerefAs x=%d\n", x)
|
||||
|
||||
p2: str = "ABC"
|
||||
total_ch: int = 0
|
||||
while c.Deref(p2) != 0:
|
||||
total_ch = total_ch + c.Deref(p2)
|
||||
p2 = p2 + 1
|
||||
stdio.printf("ptr: sum(A,B,C)=%d\n", total_ch)
|
||||
|
||||
return 0
|
||||
111
Test/App/ptr_test.py
Normal file
111
Test/App/ptr_test.py
Normal file
@@ -0,0 +1,111 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 简单指针 + 逻辑测试
|
||||
# ============================================================
|
||||
|
||||
def ptr_test() -> int:
|
||||
# 逻辑测试:if 语句
|
||||
x: int = 10
|
||||
if x:
|
||||
stdio.printf("if: x is truthy\n")
|
||||
|
||||
if 1 == 1:
|
||||
stdio.printf("if: 1==1 is truthy\n")
|
||||
|
||||
# While 循环 + 累加
|
||||
i: int = 0
|
||||
total: int = 0
|
||||
while i < 5:
|
||||
total = total + i
|
||||
i = i + 1
|
||||
stdio.printf("while: total=%d i=%d\n", total, i)
|
||||
|
||||
# For 循环
|
||||
for j in range(5):
|
||||
stdio.printf("for: j=%d\n", j)
|
||||
|
||||
# Break 测试
|
||||
for k in range(10):
|
||||
if k == 3:
|
||||
break
|
||||
stdio.printf("break: k=%d\n", k)
|
||||
|
||||
# Continue 测试
|
||||
for m in range(5):
|
||||
if m == 2:
|
||||
continue
|
||||
stdio.printf("continue: m=%d\n", m)
|
||||
|
||||
# 布尔运算 and(短路求值)
|
||||
if x > 5 and x < 100:
|
||||
stdio.printf("bool: x>5 and x<100 is true\n")
|
||||
|
||||
# 布尔运算 or(短路求值)
|
||||
if x > 100 or x > 5:
|
||||
stdio.printf("bool: x>100 or x>5 is true\n")
|
||||
|
||||
# ============================================================
|
||||
# 指针 + c.Deref / c.DerefAs 测试
|
||||
# ============================================================
|
||||
|
||||
# 字符串遍历: while c.Deref(p) != 0
|
||||
s: str = "hello"
|
||||
sp: str = s
|
||||
slen: int = 0
|
||||
while c.Deref(sp) != 0:
|
||||
slen = slen + 1
|
||||
sp = sp + 1
|
||||
stdio.printf("ptr: len(hello)=%d\n", slen)
|
||||
|
||||
# c.DerefAs 写入字符(使用 c.Addr 获取栈变量地址,字符串字面量是只读的)
|
||||
v: int = 65 # 'A'
|
||||
px: str = c.Addr(v)
|
||||
c.DerefAs(px, 88) # *px = 88
|
||||
stdio.printf("ptr: after DerefAs v=%d\n", v)
|
||||
|
||||
# 遍历字符串并累加字符值
|
||||
p2: str = "ABC"
|
||||
total_ch: int = 0
|
||||
while c.Deref(p2) != 0:
|
||||
total_ch = total_ch + c.Deref(p2)
|
||||
p2 = p2 + 1
|
||||
stdio.printf("ptr: sum(A,B,C)=%d\n", total_ch)
|
||||
|
||||
# ============================================================
|
||||
# c.Load 测试: *a = *b(加载源指针的值,存储到目标指针)
|
||||
# ============================================================
|
||||
|
||||
# 基本复制: v2 = v1
|
||||
v1: int = 42
|
||||
v2: int = 0
|
||||
c.Load(c.Addr(v2), c.Addr(v1))
|
||||
stdio.printf("ptr: c.Load v2=%d (expected 42)\n", v2)
|
||||
if v2 != 42:
|
||||
stdio.printf("[FAIL] c.Load expected 42 got %d\n", v2)
|
||||
return 1
|
||||
|
||||
# 覆盖已有值: v3 = v4
|
||||
v3: int = 100
|
||||
v4: int = 200
|
||||
c.Load(c.Addr(v3), c.Addr(v4))
|
||||
stdio.printf("ptr: c.Load overwrite v3=%d (expected 200)\n", v3)
|
||||
if v3 != 200:
|
||||
stdio.printf("[FAIL] c.Load overwrite expected 200 got %d\n", v3)
|
||||
return 1
|
||||
|
||||
# 验证源不被修改: v5 保持原值
|
||||
v5: int = 999
|
||||
v6: int = 0
|
||||
c.Load(c.Addr(v6), c.Addr(v5))
|
||||
stdio.printf("ptr: c.Load src unchanged v5=%d v6=%d (expected 999, 999)\n", v5, v6)
|
||||
if v5 != 999:
|
||||
stdio.printf("[FAIL] c.Load src changed v5=%d\n", v5)
|
||||
return 1
|
||||
if v6 != 999:
|
||||
stdio.printf("[FAIL] c.Load dst expected 999 got %d\n", v6)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
6
Test/App/simple_test.py
Normal file
6
Test/App/simple_test.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import stdio
|
||||
|
||||
def simple_test() -> int:
|
||||
stdio.printf("hello\n")
|
||||
return 0
|
||||
|
||||
9
Test/App/string_min_test.py
Normal file
9
Test/App/string_min_test.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import string
|
||||
|
||||
|
||||
def string_min_test() -> int:
|
||||
l: t.CSizeT = string.strlen("Hello")
|
||||
stdio.printf("strlen(Hello)=%lu\n", l)
|
||||
return 0
|
||||
106
Test/App/string_test.py
Normal file
106
Test/App/string_test.py
Normal file
@@ -0,0 +1,106 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import string
|
||||
|
||||
|
||||
# ============================================================
|
||||
# string_test - string.py 库函数测试
|
||||
#
|
||||
# 测试 strlen / strcmp / strncmp / atoi / strchr / strstr
|
||||
# ============================================================
|
||||
|
||||
|
||||
def test_strlen():
|
||||
stdio.printf("--- Test 1: strlen ---\n")
|
||||
|
||||
l1: t.CSizeT = string.strlen("Hello")
|
||||
stdio.printf("strlen(Hello)=%lu (expect 5)\n", l1)
|
||||
|
||||
l2: t.CSizeT = string.strlen("")
|
||||
stdio.printf("strlen()=%lu (expect 0)\n", l2)
|
||||
|
||||
l3: t.CSizeT = string.strlen("Hello, World!")
|
||||
stdio.printf("strlen(Hello, World!)=%lu (expect 13)\n", l3)
|
||||
|
||||
|
||||
def test_strcmp():
|
||||
stdio.printf("--- Test 2: strcmp ---\n")
|
||||
|
||||
r1: t.CInt = string.strcmp("abc", "abc")
|
||||
stdio.printf("strcmp(abc,abc)=%d (expect 0)\n", r1)
|
||||
|
||||
r2: t.CInt = string.strcmp("abc", "abd")
|
||||
stdio.printf("strcmp(abc,abd)=%d (expect <0)\n", r2)
|
||||
|
||||
r3: t.CInt = string.strcmp("abd", "abc")
|
||||
stdio.printf("strcmp(abd,abc)=%d (expect >0)\n", r3)
|
||||
|
||||
|
||||
def test_strncmp():
|
||||
stdio.printf("--- Test 3: strncmp ---\n")
|
||||
|
||||
r1: t.CInt = string.strncmp("abcdef", "abcXYZ", 3)
|
||||
stdio.printf("strncmp(abcdef,abcXYZ,3)=%d (expect 0)\n", r1)
|
||||
|
||||
r2: t.CInt = string.strncmp("abcdef", "abcXYZ", 4)
|
||||
stdio.printf("strncmp(abcdef,abcXYZ,4)=%d (expect <0)\n", r2)
|
||||
|
||||
|
||||
def test_atoi():
|
||||
stdio.printf("--- Test 4: atoi ---\n")
|
||||
|
||||
n1: t.CInt = string.atoi("123")
|
||||
stdio.printf("atoi(123)=%d (expect 123)\n", n1)
|
||||
|
||||
n2: t.CInt = string.atoi("-456")
|
||||
stdio.printf("atoi(-456)=%d (expect -456)\n", n2)
|
||||
|
||||
n3: t.CInt = string.atoi(" 789")
|
||||
stdio.printf("atoi( 789)=%d (expect 789)\n", n3)
|
||||
|
||||
|
||||
def test_strchr():
|
||||
stdio.printf("--- Test 5: strchr ---\n")
|
||||
|
||||
# strchr 返回指向字符的指针,不为 None 表示找到
|
||||
p: str = string.strchr("Hello", 108) # 'l' = 108
|
||||
if p is not None:
|
||||
stdio.printf("strchr(Hello,'l') found, char=%d (expect 108)\n", c.Deref(p))
|
||||
else:
|
||||
stdio.printf("strchr(Hello,'l') NOT FOUND (FAIL)\n")
|
||||
|
||||
p2: str = string.strchr("Hello", 122) # 'z' = 122
|
||||
if p2 is None:
|
||||
stdio.printf("strchr(Hello,'z') not found OK\n")
|
||||
else:
|
||||
stdio.printf("strchr(Hello,'z') FAIL (should be None)\n")
|
||||
|
||||
|
||||
def test_strstr():
|
||||
stdio.printf("--- Test 6: strstr ---\n")
|
||||
|
||||
p: str = string.strstr("Hello World", "World")
|
||||
if p is not None:
|
||||
stdio.printf("strstr(Hello,World) found OK\n")
|
||||
else:
|
||||
stdio.printf("strstr(Hello,World) NOT FOUND (FAIL)\n")
|
||||
|
||||
p2: str = string.strstr("Hello World", "xyz")
|
||||
if p2 is None:
|
||||
stdio.printf("strstr(Hello,xyz) not found OK\n")
|
||||
else:
|
||||
stdio.printf("strstr(Hello,xyz) FAIL (should be None)\n")
|
||||
|
||||
|
||||
def string_test() -> int:
|
||||
stdio.printf("=== string_test: string.py 库函数测试 ===\n\n")
|
||||
|
||||
test_strlen()
|
||||
test_strcmp()
|
||||
test_strncmp()
|
||||
test_atoi()
|
||||
test_strchr()
|
||||
test_strstr()
|
||||
|
||||
stdio.printf("\n=== string_test 完成 ===\n")
|
||||
return 0
|
||||
235
Test/App/struct_test.py
Normal file
235
Test/App/struct_test.py
Normal file
@@ -0,0 +1,235 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 纯内存结构体(class)测试
|
||||
# ============================================================
|
||||
|
||||
class Point:
|
||||
x: t.CInt
|
||||
y: t.CInt
|
||||
|
||||
|
||||
class Box:
|
||||
width: t.CInt
|
||||
height: t.CInt
|
||||
depth: t.CInt
|
||||
|
||||
|
||||
class Size:
|
||||
w: t.CInt = 100
|
||||
h: t.CInt = 200
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 枚举(t.CEnum)测试
|
||||
# ============================================================
|
||||
|
||||
class State(t.CEnum):
|
||||
Idle: t.State
|
||||
Run: t.State
|
||||
Stop: t.State
|
||||
|
||||
|
||||
class Color(t.CEnum):
|
||||
Red: t.State = 10
|
||||
Green: t.State
|
||||
Blue: t.State = 20
|
||||
Yellow: t.State
|
||||
|
||||
|
||||
class MixedType(t.CEnum):
|
||||
Small: t.CInt8T
|
||||
Big: t.CInt64T
|
||||
Medium: t.CInt16T
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 联合体(t.CUnion)测试
|
||||
# ============================================================
|
||||
|
||||
class DataUnion(t.CUnion):
|
||||
i: t.CInt
|
||||
f: t.CFloat
|
||||
l: t.CInt64T
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 主函数
|
||||
# ============================================================
|
||||
def struct_test() -> int:
|
||||
# ============================================================
|
||||
# 测试 1: 结构体字段读写
|
||||
# ============================================================
|
||||
p: Point = Point()
|
||||
p.x = 10
|
||||
p.y = 20
|
||||
stdio.printf("struct: p.x=%d p.y=%d\n", p.x, p.y)
|
||||
|
||||
# 修改字段
|
||||
p.x = 100
|
||||
p.y = 200
|
||||
stdio.printf("struct: modified p.x=%d p.y=%d\n", p.x, p.y)
|
||||
|
||||
# 字段运算
|
||||
sum_xy: int = p.x + p.y
|
||||
stdio.printf("struct: sum=%d\n", sum_xy)
|
||||
|
||||
# ============================================================
|
||||
# 测试 2: 多字段结构体
|
||||
# ============================================================
|
||||
b: Box
|
||||
b.width = 3
|
||||
b.height = 4
|
||||
b.depth = 5
|
||||
vol: int = b.width * b.height * b.depth
|
||||
stdio.printf("struct: volume=%d\n", vol)
|
||||
|
||||
# ============================================================
|
||||
# 测试 3: t.CArray 数组遍历
|
||||
# ============================================================
|
||||
arr: t.CArray[t.CInt, 5]
|
||||
arr[0] = 100
|
||||
arr[1] = 200
|
||||
arr[2] = 300
|
||||
arr[3] = 400
|
||||
arr[4] = 500
|
||||
|
||||
arr_total: int = 0
|
||||
for i in range(5):
|
||||
arr_total = arr_total + arr[i]
|
||||
stdio.printf("array: total=%d\n", arr_total)
|
||||
|
||||
# 修改数组元素
|
||||
arr[2] = 999
|
||||
stdio.printf("array: arr[2]=%d\n", arr[2])
|
||||
|
||||
# ============================================================
|
||||
# 测试 4: 指针遍历(字符串)
|
||||
# ============================================================
|
||||
s: str = "hello"
|
||||
sp: str = s
|
||||
slen: int = 0
|
||||
while c.Deref(sp) != 0:
|
||||
slen = slen + 1
|
||||
sp = sp + 1
|
||||
stdio.printf("ptr: len(hello)=%d\n", slen)
|
||||
|
||||
# 累加字符值
|
||||
p2: str = "ABC"
|
||||
total_ch: int = 0
|
||||
while c.Deref(p2) != 0:
|
||||
total_ch = total_ch + c.Deref(p2)
|
||||
p2 = p2 + 1
|
||||
stdio.printf("ptr: sum(A,B,C)=%d\n", total_ch)
|
||||
|
||||
# ============================================================
|
||||
# 测试 5: 结构体构造函数 Point() / Point(x, y)
|
||||
# ============================================================
|
||||
# 无参数构造:零初始化
|
||||
z: Point = Point()
|
||||
stdio.printf("ctor: z.x=%d z.y=%d\n", z.x, z.y)
|
||||
|
||||
# 带参数构造:按位置赋值
|
||||
p3: Point = Point(7, 8)
|
||||
stdio.printf("ctor: p3.x=%d p3.y=%d\n", p3.x, p3.y)
|
||||
|
||||
# 多字段构造
|
||||
bx: Box = Box(10, 20, 30)
|
||||
stdio.printf("ctor: bx.w=%d bx.h=%d bx.d=%d\n", bx.width, bx.height, bx.depth)
|
||||
|
||||
# ============================================================
|
||||
# 测试 6: 结构体关键字参数(乱序传参)
|
||||
# ============================================================
|
||||
# 全关键字乱序
|
||||
p4: Point = Point(y=20, x=10)
|
||||
stdio.printf("kw: p4.x=%d p4.y=%d\n", p4.x, p4.y)
|
||||
|
||||
# 混合:位置 + 关键字
|
||||
p5: Point = Point(5, y=15)
|
||||
stdio.printf("kw: p5.x=%d p5.y=%d\n", p5.x, p5.y)
|
||||
|
||||
# 多字段关键字乱序
|
||||
bx2: Box = Box(depth=30, width=10, height=20)
|
||||
stdio.printf("kw: bx2.w=%d bx2.h=%d bx2.d=%d\n", bx2.width, bx2.height, bx2.depth)
|
||||
|
||||
# ============================================================
|
||||
# 测试 7: 结构体默认赋值
|
||||
# ============================================================
|
||||
# 无参数构造:使用默认值
|
||||
sz: Size = Size()
|
||||
stdio.printf("def: sz.w=%d sz.h=%d\n", sz.w, sz.h)
|
||||
|
||||
# 位置参数覆盖默认值
|
||||
sz2: Size = Size(5, 6)
|
||||
stdio.printf("def: sz2.w=%d sz2.h=%d\n", sz2.w, sz2.h)
|
||||
|
||||
# 关键字参数覆盖默认值(乱序)
|
||||
sz3: Size = Size(h=999, w=888)
|
||||
stdio.printf("def: sz3.w=%d sz3.h=%d\n", sz3.w, sz3.h)
|
||||
|
||||
# 混合:位置参数 + 默认值(w=7 覆盖默认值,h 保持默认值 200)
|
||||
sz4: Size = Size(7)
|
||||
stdio.printf("def: sz4.w=%d sz4.h=%d\n", sz4.w, sz4.h)
|
||||
|
||||
# ============================================================
|
||||
# 测试 8: 枚举自动赋值(Idle=0, Run=1, Stop=2)
|
||||
# ============================================================
|
||||
s_idle: int = State.Idle
|
||||
s_run: int = State.Run
|
||||
s_stop: int = State.Stop
|
||||
stdio.printf("enum: Idle=%d Run=%d Stop=%d\n", s_idle, s_run, s_stop)
|
||||
|
||||
# ============================================================
|
||||
# 测试 9: 枚举手动赋值(Red=10, Green=11, Blue=20, Yellow=21)
|
||||
# ============================================================
|
||||
c_red: int = Color.Red
|
||||
c_green: int = Color.Green
|
||||
c_blue: int = Color.Blue
|
||||
c_yellow: int = Color.Yellow
|
||||
stdio.printf("enum: Red=%d Green=%d Blue=%d Yellow=%d\n",
|
||||
c_red, c_green, c_blue, c_yellow)
|
||||
|
||||
# ============================================================
|
||||
# 测试 10: 枚举混用数字类型(基准类型应为 i64)
|
||||
# ============================================================
|
||||
m_small: int = MixedType.Small
|
||||
m_big: int = MixedType.Big
|
||||
m_medium: int = MixedType.Medium
|
||||
stdio.printf("enum: Small=%d Big=%d Medium=%d\n", m_small, m_big, m_medium)
|
||||
|
||||
# 枚举参与运算
|
||||
s_sum: int = State.Idle + State.Run + State.Stop
|
||||
stdio.printf("enum: sum(Idle,Run,Stop)=%d\n", s_sum)
|
||||
|
||||
# 枚举比较
|
||||
if State.Idle == 0:
|
||||
stdio.printf("enum: Idle==0 true\n")
|
||||
if Color.Red == 10:
|
||||
stdio.printf("enum: Red==10 true\n")
|
||||
if State.Run != State.Stop:
|
||||
stdio.printf("enum: Run!=Stop true\n")
|
||||
|
||||
# ============================================================
|
||||
# 测试 11: 联合体字段读写
|
||||
# ============================================================
|
||||
u: DataUnion
|
||||
u.i = 42
|
||||
stdio.printf("union: u.i=%d\n", u.i)
|
||||
|
||||
# 写入 l 字段(覆盖 i 的内存,因为 l 是 i64)
|
||||
u.l = 20015998343868
|
||||
stdio.printf("union: u.l=%lld\n", u.l)
|
||||
|
||||
# ============================================================
|
||||
# 测试 12: 联合体共享内存验证
|
||||
# ============================================================
|
||||
u2: DataUnion
|
||||
u2.i = 1
|
||||
# 写入 l 后,i 的值已被覆盖(不再是 1)
|
||||
u2.l = 100
|
||||
if u2.i != 1:
|
||||
stdio.printf("union: shared memory verified\n")
|
||||
|
||||
return 0
|
||||
109
Test/App/test_main.py
Normal file
109
Test/App/test_main.py
Normal file
@@ -0,0 +1,109 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import testcheck
|
||||
from stdint import *
|
||||
from asm_test import asm_test
|
||||
from attr_test import attr_test
|
||||
from augassign_test import augassign_test
|
||||
from closure_test import closure_test
|
||||
from deco_test import deco_test
|
||||
from deref_min_test import deref_min_test
|
||||
from deref_test import deref_test
|
||||
from eq_test import eq_test
|
||||
from float_test import float_test
|
||||
from flow_test import flow_test
|
||||
from for_test import for_test
|
||||
from func_test import func_test
|
||||
from llvmir_test import llvmir_test
|
||||
from oop_test import oop_test
|
||||
from ptr_only_test import ptr_only_test
|
||||
from ptr_test import ptr_test
|
||||
from simple_test import simple_test
|
||||
from string_min_test import string_min_test
|
||||
from string_test import string_test
|
||||
from struct_test import struct_test
|
||||
from type_bit_test import type_bit_test
|
||||
from vtable_test import vtable_test
|
||||
from inherit_test import inherit_test
|
||||
from func_vtable_test import func_vtable_test
|
||||
from virtual_dispatch_test import virtual_dispatch_test
|
||||
from new_test import new_test
|
||||
from namespace_test import namespace_test
|
||||
from testcheck_test import testcheck_test
|
||||
from opovl_test import opovl_test
|
||||
from generic_test import generic_test
|
||||
|
||||
|
||||
def main() -> int:
|
||||
stdio.printf("===== TransPyV Test Suite =====\n\n")
|
||||
|
||||
r: int = 0
|
||||
|
||||
stdio.fflush(None)
|
||||
r = asm_test()
|
||||
stdio.fflush(None)
|
||||
r = attr_test()
|
||||
stdio.fflush(None)
|
||||
r = augassign_test()
|
||||
stdio.fflush(None)
|
||||
r = closure_test()
|
||||
stdio.fflush(None)
|
||||
r = deco_test()
|
||||
stdio.fflush(None)
|
||||
r = deref_min_test()
|
||||
stdio.fflush(None)
|
||||
r = deref_test()
|
||||
stdio.fflush(None)
|
||||
r = eq_test()
|
||||
stdio.fflush(None)
|
||||
r = float_test()
|
||||
stdio.fflush(None)
|
||||
r = flow_test()
|
||||
stdio.fflush(None)
|
||||
r = for_test()
|
||||
stdio.fflush(None)
|
||||
r = func_test()
|
||||
stdio.fflush(None)
|
||||
r = llvmir_test()
|
||||
stdio.fflush(None)
|
||||
r = oop_test()
|
||||
stdio.fflush(None)
|
||||
r = ptr_only_test()
|
||||
stdio.fflush(None)
|
||||
r = ptr_test()
|
||||
stdio.fflush(None)
|
||||
r = simple_test()
|
||||
stdio.fflush(None)
|
||||
r = string_min_test()
|
||||
stdio.fflush(None)
|
||||
r = string_test()
|
||||
stdio.fflush(None)
|
||||
r = struct_test()
|
||||
stdio.fflush(None)
|
||||
r = type_bit_test()
|
||||
stdio.fflush(None)
|
||||
r = vtable_test()
|
||||
stdio.fflush(None)
|
||||
r = inherit_test()
|
||||
stdio.fflush(None)
|
||||
r = func_vtable_test()
|
||||
stdio.fflush(None)
|
||||
r = virtual_dispatch_test()
|
||||
stdio.fflush(None)
|
||||
r = new_test()
|
||||
stdio.fflush(None)
|
||||
r = namespace_test()
|
||||
stdio.fflush(None)
|
||||
r = testcheck_test()
|
||||
stdio.fflush(None)
|
||||
r = opovl_test()
|
||||
stdio.fflush(None)
|
||||
|
||||
stdio.printf("[TM] before generic_test\n")
|
||||
stdio.fflush(None)
|
||||
r = generic_test()
|
||||
stdio.printf("[TM] after generic_test r=%d\n", r)
|
||||
stdio.fflush(None)
|
||||
|
||||
stdio.printf("\n===== Test Suite Complete =====\n")
|
||||
return r
|
||||
37
Test/App/testcheck_test.py
Normal file
37
Test/App/testcheck_test.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import string
|
||||
import testcheck
|
||||
|
||||
|
||||
# ============================================================
|
||||
# testcheck_test - 测试 includes/testcheck 库导入与调用
|
||||
#
|
||||
# 验证命名空间隔离下,import testcheck + 模块限定函数调用能正常工作。
|
||||
# 同时测试 string 库的模块限定调用。
|
||||
# ============================================================
|
||||
def testcheck_test() -> int:
|
||||
testcheck.begin("testcheck_test")
|
||||
|
||||
testcheck.section("Arithmetic")
|
||||
a: int = 3 + 4
|
||||
testcheck.check(a == 7, "3+4=7", "3+4!=7")
|
||||
|
||||
b: int = 10 - 3
|
||||
testcheck.check(b == 7, "10-3=7", "10-3!=7")
|
||||
|
||||
m: int = 6 * 7
|
||||
testcheck.check(m == 42, "6*7=42", "6*7!=42")
|
||||
|
||||
testcheck.section("String")
|
||||
slen: int = string.strlen("hello")
|
||||
testcheck.check(slen == 5, "strlen(hello)=5", "strlen(hello)!=5")
|
||||
|
||||
scmp: int = string.strcmp("abc", "abc")
|
||||
testcheck.check(scmp == 0, "strcmp(abc,abc)=0", "strcmp(abc,abc)!=0")
|
||||
|
||||
testcheck.section("Module Import")
|
||||
testcheck.info("testcheck module imported and called successfully")
|
||||
testcheck.ok("import testcheck works")
|
||||
|
||||
return testcheck.end()
|
||||
26
Test/App/type_bit_test.py
Normal file
26
Test/App/type_bit_test.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
def type_bit_test() -> int:
|
||||
ti: t.CInt = 100
|
||||
ti32: t.CInt32T = 200
|
||||
tui32: t.CUInt32T = 300
|
||||
stdio.printf("type: CInt=%d CInt32T=%d CUInt32T=%d\n", ti, ti32, tui32)
|
||||
|
||||
tl: t.CLong = 1000
|
||||
tll: t.CLongLong = 2000
|
||||
ti64: t.CInt64T = 3000
|
||||
tsize: t.CSizeT = 4000
|
||||
stdio.printf("type: CLong=%d CLongLong=%d CInt64T=%d CSizeT=%d\n", tl, tll, ti64, tsize)
|
||||
|
||||
ba: int = 240
|
||||
bb: int = 15
|
||||
stdio.printf("bit: 240&15=%d\n", ba & bb)
|
||||
stdio.printf("bit: 240|15=%d\n", ba | bb)
|
||||
stdio.printf("bit: 240^15=%d\n", ba ^ bb)
|
||||
stdio.printf("bit: 240<<2=%d\n", ba << 2)
|
||||
stdio.printf("bit: 240>>2=%d\n", ba >> 2)
|
||||
stdio.printf("bit: 17%%5=%d\n", 17 % 5)
|
||||
|
||||
return 0
|
||||
83
Test/App/virtual_dispatch_test.py
Normal file
83
Test/App/virtual_dispatch_test.py
Normal file
@@ -0,0 +1,83 @@
|
||||
import stdio
|
||||
import t, c
|
||||
import string
|
||||
from inherit_test import Animal, Dog
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 虚分派测试:通过虚表指针验证虚分派机制
|
||||
#
|
||||
# 本测试验证:方法调用通过对象的 __vtable__ 字段进行虚分派,
|
||||
# 而非通过变量声明类型直接调用。
|
||||
#
|
||||
# 测试方法:
|
||||
# 1. 创建 Animal 对象 a(Animal 虚表,Speak 返回 0)
|
||||
# 2. 创建 Dog 对象 d
|
||||
# 3. 用内联汇编将 d 的虚表指针复制到 a
|
||||
# 4. 调用 a.Speak() — 应返回 1(Dog.Speak),证明虚分派生效
|
||||
#
|
||||
# 如果是直接调用(非虚分派),a.Speak() 会调用 Animal.Speak 返回 0
|
||||
#
|
||||
# 注意:Animal 和 Dog 类从 inherit_test.py 导入(命名空间隔离)
|
||||
# ============================================================
|
||||
|
||||
|
||||
def virtual_dispatch_test() -> int:
|
||||
stdio.printf("vdispatch: === Test Start ===\n")
|
||||
|
||||
# 创建对象
|
||||
a: Animal = Animal(42)
|
||||
d: Dog = Dog(100, 7)
|
||||
|
||||
# ============================================================
|
||||
# 测试 1: 直接分派(基线验证)
|
||||
# ============================================================
|
||||
stdio.printf("vdispatch: === Test 1: Direct Dispatch ===\n")
|
||||
|
||||
a_speak: int = a.Speak()
|
||||
stdio.printf("vdispatch: a.Speak()=%d (expected 0)\n", a_speak)
|
||||
if a_speak != 0:
|
||||
stdio.printf("[FAIL] a.Speak()=%d expected 0\n", a_speak)
|
||||
return 1
|
||||
|
||||
d_speak: int = d.Speak()
|
||||
stdio.printf("vdispatch: d.Speak()=%d (expected 1)\n", d_speak)
|
||||
if d_speak != 1:
|
||||
stdio.printf("[FAIL] d.Speak()=%d expected 1\n", d_speak)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# 测试 2: 虚分派验证(复制虚表指针)
|
||||
#
|
||||
# 将 Dog 的虚表指针复制到 Animal 对象 a
|
||||
# 虚表指针位于结构体偏移 0(__vtable__ 字段)
|
||||
# 复制后 a.Speak() 应通过虚表分发到 Dog.Speak(返回 1)
|
||||
# ============================================================
|
||||
stdio.printf("vdispatch: === Test 2: Virtual Dispatch ===\n")
|
||||
|
||||
# 使用 string.memcpy 复制虚表指针(8字节,结构体偏移0)
|
||||
# 将 d 的虚表指针复制到 a,使 a.Speak() 分发到 Dog.Speak
|
||||
string.memcpy(c.Addr(a), c.Addr(d), 8)
|
||||
|
||||
a_speak2: int = a.Speak()
|
||||
stdio.printf("vdispatch: a.Speak()=%d (expected 1 after vtable copy)\n", a_speak2)
|
||||
if a_speak2 != 1:
|
||||
stdio.printf("[FAIL] a.Speak()=%d expected 1 after vtable copy\n", a_speak2)
|
||||
return 1
|
||||
|
||||
# ============================================================
|
||||
# 测试 3: GetName 验证(未被覆盖的虚方法)
|
||||
#
|
||||
# Dog 没有覆盖 GetName,Dog 虚表中 GetName 槽位指向 Animal.GetName
|
||||
# a.GetName() 应返回 a.name (42),证明虚表槽位一致性
|
||||
# ============================================================
|
||||
stdio.printf("vdispatch: === Test 3: GetName After VTable Copy ===\n")
|
||||
|
||||
a_name: int = a.GetName()
|
||||
stdio.printf("vdispatch: a.GetName()=%d (expected 42)\n", a_name)
|
||||
if a_name != 42:
|
||||
stdio.printf("[FAIL] a.GetName()=%d expected 42\n", a_name)
|
||||
return 1
|
||||
|
||||
stdio.printf("vdispatch: === All Tests Passed ===\n")
|
||||
return 0
|
||||
63
Test/App/vtable_test.py
Normal file
63
Test/App/vtable_test.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import stdio
|
||||
import t, c
|
||||
|
||||
|
||||
@t.CVTable
|
||||
class Animal:
|
||||
name: t.CInt
|
||||
|
||||
def __init__(self, n: t.CInt):
|
||||
self.name = n
|
||||
|
||||
def GetName(self) -> t.CInt:
|
||||
return self.name
|
||||
|
||||
def Speak(self) -> t.CInt:
|
||||
return 0
|
||||
|
||||
|
||||
@t.CVTable
|
||||
class Shape:
|
||||
sides: t.CInt
|
||||
|
||||
def SetSides(self, n: t.CInt) -> t.CInt:
|
||||
self.sides = n
|
||||
return 0
|
||||
|
||||
def GetSides(self) -> t.CInt:
|
||||
return self.sides
|
||||
|
||||
|
||||
def vtable_test() -> int:
|
||||
stdio.printf("vtable: === Test Start ===\n")
|
||||
|
||||
# 测试 1: Animal 虚方法调用(无参,访问 self 字段)
|
||||
a: Animal = Animal(42)
|
||||
name: int = a.GetName()
|
||||
stdio.printf("vtable: a.GetName()=%d (expected 42)\n", name)
|
||||
if name != 42:
|
||||
stdio.printf("[FAIL] a.GetName()=%d expected 42\n", name)
|
||||
return 1
|
||||
|
||||
speak: int = a.Speak()
|
||||
stdio.printf("vtable: a.Speak()=%d (expected 0)\n", speak)
|
||||
if speak != 0:
|
||||
stdio.printf("[FAIL] a.Speak()=%d expected 0\n", speak)
|
||||
return 1
|
||||
|
||||
# 测试 2: Shape 虚方法调用(带参,修改 self 字段)
|
||||
s: Shape = Shape()
|
||||
r: int = s.SetSides(4)
|
||||
stdio.printf("vtable: s.SetSides(4)=%d (expected 0)\n", r)
|
||||
if r != 0:
|
||||
stdio.printf("[FAIL] s.SetSides(4)=%d expected 0\n", r)
|
||||
return 1
|
||||
|
||||
sides: int = s.GetSides()
|
||||
stdio.printf("vtable: s.GetSides()=%d (expected 4)\n", sides)
|
||||
if sides != 4:
|
||||
stdio.printf("[FAIL] s.GetSides()=%d expected 4\n", sides)
|
||||
return 1
|
||||
|
||||
stdio.printf("vtable: === All Tests Passed ===\n")
|
||||
return 0
|
||||
Reference in New Issue
Block a user