Files
Viper_RegressionTesting/NewTest/App/main.vp
T
2026-10-17 21:57:03 +08:00

83 lines
3.5 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from stdint import *
import win32.win32console
import stdio
import stdlib
import memhub
# =============================================================================
# M2.4 `new` 描述符分配:三来源各自落地不同(IR 差异见下方注释)
# stack → 帧内 alloca(无 malloc 调用,随帧失效)
# heap → call i8* @malloc(i64 sizeof) + bitcast 到 T*
# memgr → call i8* @<Mgr>.alloc(i64 sizeof) + bitcast 到 T*
# 本工程做冒烟验证:能编译、能跑出正确字段值。
# 描述符顺序无关;**缺省规则**(D3 / §3.2):
# 省略来源 → heap
# 省略生命期 → 由**来源**决定:stack → slife(帧生命期),heap / memgr → hlife
# 于是:`new stack Point(7,8)` ≡ `new stack slife Point(7,8)`(stack 默认 slife)
# `new Point(3,4)` ≡ `new heap hlife Point(3,4)`(完全省略即堆 + 自由生命期)
# =============================================================================
novirtual class Point:
x: int
y: int
# §7.2/M4 前提件冒烟:泛型类的 callee 是下标形式(Box[int]),`new` 必须先特化再取存储
class Box[T]:
v: T
export def main() -> int:
win32.win32console.SetConsoleCP(65001)
win32.win32console.SetConsoleOutputCP(65001)
# (1) stack:等价既有写法 &Point(1, 2),生命期随帧
p1: Point* = new stack slife Point(1, 2)
stdio.printf("stack: %d %d\n", p1.x, p1.y)
# (2) heap:malloc(sizeof(Point)) + 构造(生命期默认 hlife)
p2: Point* = new heap Point(3, 4)
stdio.printf("heap : %d %d\n", p2.x, p2.y)
# (3) stack + **生命期缺省** → slife(与 (1) 显式写 slife 等价,专门验证缺省规则)
p3: Point* = new stack Point(7, 8)
stdio.printf("stack默认slife: %d %d\n", p3.x, p3.y)
# (4) memgr(x):从 memhub 管理器取存储(管理器构造方式见 Test/MemhubTest)
arena: bytes = stdlib.malloc(65536)
m: memhub.MemBuddy = memhub.MemBuddy(arena, 65536)
p4: Point* = new memgr(m) hlife Point(5, 6)
stdio.printf("memgr: %d %d\n", p4.x, p4.y)
stdlib.free(arena)
# (5) §7.2/M4 前提件:**泛型类**的存储也走 `new` 描述符(`Box[int]` 先特化,再复用描述符存储)。
# 这是把 list/dict/hashtable 从"类内 __new__ 从池取本体"迁到"调用点 new memgr(pool) …"的前提:
# _translate_generic_ctor_call 之前只会 _alloca_at_entry(栈),会忽略描述符存储。
arena2: bytes = stdlib.malloc(65536)
m2: memhub.MemBuddy = memhub.MemBuddy(arena2, 65536)
b: Box[int]* = new memgr(m2) hlife Box[int](7)
stdio.printf("generic-in-pool: %d\n", b.v)
stdlib.free(arena2)
# (6) 括号可省 + 标量/数组:`new stack char` / `new stack [4]char`(类型按**注解规则**解析,
# 故 `[N]T` 前导数组声明符与 `T*` 后缀都认)。数组返回**首元素指针**(数组名退化),
# 所以能直接存进 `char*`;未写到的位置是零初始化。
c6: char* = new stack char
if c6[0] != 0: return 1
l6: char* = new stack [4]char
l6[0] = 'A'
l6[1] = 'B'
if l6[0] != 'A': return 2
if l6[1] != 'B': return 3
if l6[3] != 0: return 4
stdio.printf("scalar/array: ok\n")
# 非法组合(应报 LifetimeError)——要验证时打开其中一条:
# 1) 语义矛盾:bad: Point* = new stack hlife Point(7, 8)
# 2) 多来源 :new stack heap Point(7, 8) → 解析期报错
# 3) 多生命期:new heap slife hlife Point(7, 8) → 解析期报错
return 0