把 81 个 .vp 文件的中文 # 注释与三引号文档串改写为简洁英文,每个连续注释块 <=2 行;运行时中文字符串字面量(testcheck.begin/print 等用户可见消息)保持原样。骨架比对 HEAD 与工作区 112 文件漂移 0,全量 77/77 顺序回归通过。
269 lines
8.1 KiB
Plaintext
269 lines
8.1 KiB
Plaintext
import t
|
|
from stdint import *
|
|
from stdio import printf
|
|
from stdlib import malloc
|
|
import testcheck
|
|
|
|
|
|
# ============================================================
|
|
# Test 1: @property getter
|
|
# ============================================================
|
|
class Rect:
|
|
width: int
|
|
height: int
|
|
|
|
def __new__(self, w: int, h: int) -> 'Rect' | t.CPtr:
|
|
return t.CPtr(malloc(Rect.__sizeof__()))
|
|
|
|
def __init__(self, w: int, h: int):
|
|
self.width = w
|
|
self.height = h
|
|
|
|
@property
|
|
def area(self) -> int:
|
|
return self.width * self.height
|
|
|
|
@property
|
|
def is_square(self) -> bool:
|
|
return self.width == self.height
|
|
|
|
|
|
def test_property_getter():
|
|
testcheck.section("@property getter")
|
|
r1: Rect = Rect(3, 4)
|
|
testcheck.check(r1.area == 12, "area == 12", "area expect 12")
|
|
testcheck.check(not r1.is_square, "not square", "should not be square")
|
|
r2: Rect = Rect(5, 5)
|
|
testcheck.check(r2.area == 25, "square area == 25", "square area expect 25")
|
|
testcheck.check(r2.is_square, "is_square", "should be square")
|
|
|
|
|
|
# ============================================================
|
|
# Test 2: @property.setter
|
|
# ============================================================
|
|
class Temperature:
|
|
_celsius: double
|
|
|
|
def __new__(self, celsius_val: double) -> 'Temperature' | t.CPtr:
|
|
return t.CPtr(malloc(Temperature.__sizeof__()))
|
|
|
|
def __init__(self, celsius_val: double):
|
|
self._celsius = celsius_val
|
|
|
|
@property
|
|
def celsius(self) -> double:
|
|
return self._celsius
|
|
|
|
@celsius.setter
|
|
def celsius(self, val: double):
|
|
self._celsius = val
|
|
|
|
@property
|
|
def fahrenheit(self) -> double:
|
|
return self._celsius * 1.8 + 32.0
|
|
|
|
|
|
def test_property_setter():
|
|
testcheck.section("@property.setter")
|
|
tmp1: Temperature = Temperature(0.0)
|
|
testcheck.check(tmp1.fahrenheit > 31.9 and tmp1.fahrenheit < 32.1, "0C == 32F", "0C expect 32F")
|
|
tmp1.celsius = 100.0
|
|
testcheck.check(tmp1.fahrenheit > 211.9 and tmp1.fahrenheit < 212.1, "100C == 212F", "100C expect 212F")
|
|
testcheck.check(tmp1.celsius > 99.9 and tmp1.celsius < 100.1, "celsius == 100", "celsius expect 100")
|
|
|
|
|
|
# ============================================================
|
|
# Test 3: @property.getter redefinition
|
|
# ============================================================
|
|
class Counter:
|
|
_count: int
|
|
|
|
def __new__(self) -> 'Counter' | t.CPtr:
|
|
return t.CPtr(malloc(Counter.__sizeof__()))
|
|
|
|
def __init__(self):
|
|
self._count = 0
|
|
|
|
@property
|
|
def value(self) -> int:
|
|
return self._count
|
|
|
|
@value.setter
|
|
def value(self, v: int):
|
|
self._count = v
|
|
|
|
|
|
def test_property_getter_redef():
|
|
testcheck.section("@property.getter redef")
|
|
cnt: Counter = Counter()
|
|
testcheck.check(cnt.value == 0, "init == 0", "init expect 0")
|
|
cnt.value = 42
|
|
testcheck.check(cnt.value == 42, "set == 42", "set expect 42")
|
|
|
|
|
|
# ============================================================
|
|
# Test 4: @property.deleter
|
|
# ============================================================
|
|
class Config:
|
|
_value: int
|
|
_deleted: int
|
|
|
|
def __new__(self, v: int) -> 'Config' | t.CPtr:
|
|
return t.CPtr(malloc(Config.__sizeof__()))
|
|
|
|
def __init__(self, v: int):
|
|
self._value = v
|
|
self._deleted = 0
|
|
|
|
@property
|
|
def value(self) -> int:
|
|
return self._value
|
|
|
|
@value.setter
|
|
def value(self, v: int):
|
|
self._value = v
|
|
|
|
@value.deleter
|
|
def value(self):
|
|
self._value = 0
|
|
self._deleted = 1
|
|
|
|
def is_deleted(self) -> bool:
|
|
return self._deleted != 0
|
|
|
|
|
|
def test_property_deleter():
|
|
testcheck.section("@property.deleter")
|
|
cfg: Config = Config(99)
|
|
testcheck.check(cfg.value == 99, "init == 99", "init expect 99")
|
|
testcheck.check(not cfg.is_deleted(), "not deleted", "should not be deleted")
|
|
del cfg.value
|
|
testcheck.check(cfg.value == 0, "after del == 0", "after del expect 0")
|
|
testcheck.check(cfg.is_deleted(), "is_deleted", "should be deleted")
|
|
|
|
|
|
# ============================================================
|
|
# Test 5: @staticmethod
|
|
# ============================================================
|
|
class MathUtils:
|
|
@staticmethod
|
|
def add(a: int, b: int) -> int:
|
|
return a + b
|
|
|
|
@staticmethod
|
|
def max_val(a: int, b: int) -> int:
|
|
return a if a > b else b
|
|
|
|
|
|
def test_staticmethod():
|
|
testcheck.section("@staticmethod")
|
|
# call via class name
|
|
testcheck.check(MathUtils.add(3, 4) == 7, "MathUtils.add(3,4)==7", "MathUtils.add(3,4) expect 7")
|
|
testcheck.check(MathUtils.max_val(5, 10) == 10, "MathUtils.max(5,10)==10", "MathUtils.max(5,10) expect 10")
|
|
|
|
|
|
# ============================================================
|
|
# Test 6: @classmethod
|
|
# ============================================================
|
|
class Point:
|
|
x: double
|
|
y: double
|
|
|
|
def __new__(self, x: double, y: double) -> 'Point' | t.CPtr:
|
|
return t.CPtr(malloc(Point.__sizeof__()))
|
|
|
|
def __init__(self, x: double, y: double):
|
|
self.x = x
|
|
self.y = y
|
|
|
|
@classmethod
|
|
def origin(cls: Point) -> Point:
|
|
return Point(0.0, 0.0)
|
|
|
|
@classmethod
|
|
def from_int(cls: Point, x: int, y: int) -> Point:
|
|
return Point(x * 1.0, y * 1.0)
|
|
|
|
def dist_sq(self) -> double:
|
|
return self.x * self.x + self.y * self.y
|
|
|
|
|
|
def test_classmethod():
|
|
testcheck.section("@classmethod")
|
|
# call via class name
|
|
p1: Point = Point.origin()
|
|
testcheck.check(p1.x > -0.01 and p1.x < 0.01, "origin.x ~= 0", "origin.x expect ~0")
|
|
testcheck.check(p1.y > -0.01 and p1.y < 0.01, "origin.y ~= 0", "origin.y expect ~0")
|
|
testcheck.check(p1.dist_sq() < 0.01, "origin.dist ~= 0", "origin.dist expect ~0")
|
|
|
|
p2: Point = Point.from_int(3, 4)
|
|
testcheck.check(p2.x > 2.99 and p2.x < 3.01, "from_int(3,4).x ~= 3", "from_int(3,4).x expect ~3")
|
|
testcheck.check(p2.y > 3.99 and p2.y < 4.01, "from_int(3,4).y ~= 4", "from_int(3,4).y expect ~4")
|
|
testcheck.check(p2.dist_sq() > 24.99 and p2.dist_sq() < 25.01, "dist_sq ~= 25", "dist_sq expect ~25")
|
|
|
|
|
|
# ============================================================
|
|
# Test 7: combined @property + @staticmethod + @classmethod
|
|
# ============================================================
|
|
class Circle:
|
|
_radius: double
|
|
|
|
def __new__(self, r: double) -> 'Circle' | t.CPtr:
|
|
return t.CPtr(malloc(Circle.__sizeof__()))
|
|
|
|
def __init__(self, r: double):
|
|
self._radius = r
|
|
|
|
@property
|
|
def radius(self) -> double:
|
|
return self._radius
|
|
|
|
@radius.setter
|
|
def radius(self, val: double):
|
|
self._radius = val
|
|
|
|
@property
|
|
def area(self) -> double:
|
|
return 3.14159265 * self._radius * self._radius
|
|
|
|
@staticmethod
|
|
def is_unit(r: double) -> bool:
|
|
return r > 0.99 and r < 1.01
|
|
|
|
@classmethod
|
|
def unit(cls: Circle) -> Circle:
|
|
return Circle(1.0)
|
|
|
|
|
|
def test_combined():
|
|
testcheck.section("Combined @property + @staticmethod + @classmethod")
|
|
# first test direct construction
|
|
cr0: Circle = Circle(1.0)
|
|
testcheck.check(cr0.radius > 0.99 and cr0.radius < 1.01, "direct radius ~= 1", "direct radius expect ~1")
|
|
testcheck.check(cr0.area > 3.14 and cr0.area < 3.15, "direct area ~= pi", "direct area expect ~pi")
|
|
cr0.radius = 2.0
|
|
testcheck.check(cr0.radius > 1.99 and cr0.radius < 2.01, "direct radius 2.0", "direct radius expect 2.0")
|
|
testcheck.check(cr0.area > 12.56 and cr0.area < 12.58, "direct area ~= 4pi", "direct area expect ~4pi")
|
|
# test classmethod
|
|
cr1: Circle = Circle.unit()
|
|
testcheck.check(cr1.radius > 0.99 and cr1.radius < 1.01, "unit radius ~= 1", "unit radius expect ~1")
|
|
testcheck.check(Circle.is_unit(1.0), "is_unit(1.0)", "is_unit(1.0) should be true")
|
|
testcheck.check(not Circle.is_unit(2.0), "not is_unit(2.0)", "is_unit(2.0) should be false")
|
|
|
|
|
|
# ============================================================
|
|
# main
|
|
# ============================================================
|
|
def main() -> int | t.CExport:
|
|
testcheck.begin("Builtin Decorator Test")
|
|
|
|
test_property_getter()
|
|
test_property_setter()
|
|
test_property_getter_redef()
|
|
test_property_deleter()
|
|
test_staticmethod()
|
|
test_classmethod()
|
|
test_combined()
|
|
|
|
return testcheck.end()
|