83 lines
3.5 KiB
Plaintext
83 lines
3.5 KiB
Plaintext
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
|