-
Notifications
You must be signed in to change notification settings - Fork 0
Advanced zh
English | 中文 | Русский | Español | Português | 繁體中文 | Deutsch
进阶课程:类型化智能引用、调用原生 C 库、内存管理、性能、把注解当作设计工具,以及一个完整的动手项目。
智能引用(smart reference)是一个指向左值(lvalue)的类型化值。它由 权限 × 跟随层 × 基本类型 声明:
&<permission> <follow> <base type> <name> = &<lvalue>;
-
权限(Permissions)(7 种):
r读、w写、m移动(指针)、rw、rm、wm、rwm。 -
跟随层(Follows)(4 种):
u程序层(Unistream)、f方法层、a作用域/区域层、t线程层。 -
基本类型:
int/double/float/string/char/ 数组 / 类——泛型。
也就是 7 × 4 = 28 种引用类型。
int counter = 0;
&w u int wr = &counter; // writable program-level ref
Ref::write(wr, 10);
&r u int rr = &counter; // read-only ref
CIO::println(get Ref::read(rr)); // 10
&rw u int rw = &counter; // read-write
CIO::println(get rw); // 10
rw = 5;
CIO::println(counter); // 5
有了 m,引用就是一个移动指针(类似 C 语言中的 a++):
ALL a = new int[3];
a[0] = 10; a[1] = 20; a[2] = 30;
&m u int mp = &a[1];
CIO::println(get mp); // 20
mp++;
CIO::println(get mp); // 30
mp = 99; // writes through the pointer
CIO::println(a[2]); // 99
CIO::println(cause Ref::move(mp)); // refused: pointer moved out of bounds
引用会拒绝其权限所禁止的操作——而拒绝原因本身也是一个值:
CIO::println(cause Ref::write(rr, 99));
// Ref refused: reference is read-only, cannot write
注解在流和方法上声明契约:
// A stream that must never be forked again:
Stream Sealed {
void ping();
} @unfork
Sealed BadFork {} // startup: refused: stream Sealed is @unfork, cannot fork
// A read-only stream: users may not call write methods:
Stream ReadOnly {
int count;
void bump();
int get();
}
ReadOnly RO {
void bump() { this::count = count + 1; } @write
int get() { res count; } @read
} @onlyread
- 方法上的
@write/@read显式声明其读写性质——它们优先于 AST 启发式推断(一个看起来只读的方法体可以被声明为写方法,反之亦然)。 -
@onlyread拒绝在流上调用任何写方法。 -
@unfork拒绝所有派生路径,包括对@unfork类执行new。
流可以绑定一个共享库:
Stream m & "libm.so.6"; // bind libm
Main {
void exec() {
CIO::println(get m::sin(0)); // 0
CIO::println(get m::pow(2, 10)); // 1024
}
}
二进制函数以 double(*)(double, ...)(最多 6 个参数)的形式调用;导出的符号成为流方法。bio_dlsym / 平台 shim 处理 dlopen/LoadLibrary 的差异,因此在 Windows 上同样可用。
- 解释器使用基于块(block-based)的竞技场(arena)——分配的内存永远不会移动。
- 默认限制:解释模式下 256 MiB;
0表示不限制。 - 限制参数:
bio -e 256M script.bio(或-e 1G、-e 0)。 - 编译产物:无限制,除非在环境中设置了
BIO_MEM_LIMIT;bio shell build会把该行为嵌入生成的 main 中。 - 达到限制时,程序会以清晰的提示停止:
memory limit exceeded (limit N bytes)。
-
缓存:热路径上的流和方法会被缓存(
stream_cache/method_cache)——对同名对象的重复查找是 O(1) 的。 -
增量编译:
bio build对每个模块的源码做哈希;只有变更的模块会重新编译(N module(s) cached, M recompiled)。 -
编译模式:
bio shell build把解释器运行时链接进一个独立可执行文件——启动瞬时完成,产物在任意机器上无需bio即可运行。
make bin(通过 tools/make-dist.sh)使用 zig 为所有平台交叉编译发布树——不需要外部 SDK:
make bin
# bin/linux-x86_64/bin/bio + lib/libbio.so
# bin/win64/bin/bio.exe + lib/bio.dll + bio.bat
# bin/macos-arm64/bin/bio + lib/libbio.dylib
# ...支持的平台:linux-x86_64、linux-arm64、win32、win64、win-arm64、macos-x86_64、macos-arm64。需要 PATH 中有 zig >= 0.14。
内部实现:启动器与 lib/ 中的共享运行时动态链接(rpath $ORIGIN/../lib);Windows 使用 bio.bat 设置 PATH。POSIX 上线程使用 ucontext,Windows 上使用 Win32 fibers;二进制库通过平台 shim 使用 dlopen 或 LoadLibrary。
我们来构建一个词频统计器:读取文件、统计单词数、打印排序报告。
bio init wordcountprogram main;
need function countWords; // provided by utils/counter.bio
Main {
void exec() {
if (CIO::getln() == "") { } // (placeholder for arg reading)
FIO::open("input.txt");
string text = FIO::readFile("input.txt");
ALL report = countWords(text);
CIO::println(get report);
}
}
program utils;
function countWords(text string) {
// SIO lets us scan word by word through a string buffer.
int words = 0;
for (int i = 0; i < text::length(); i = i + 1;) {
char c = text[i];
if (c == ' ' || c == '\n' || c == '\t') {
words = words + 1;
}
}
res words + 1; // last word has no trailing space
}
bio build . -s # standalone executable
bio build . -m # packaged .img with the platform runtime
bio run . # interpret directlybio build . -m wordcount.zip # one distributable file这就是完整的循环:源码 → 验证过的包 → 独立二进制 → 跨平台包。
-
bio --tokens file.bio——转储词法分析器的 token 流。 - 拒绝消息是一等公民:
cause expr精确显示请求失败的原因。 - 用
make PROFILE=sanitize编译,获得 ASan + UBSan 构建。
- Home
- Beginner — first steps
- Intermediate — real usage
- Advanced — masterclass
- Build & Run
- Packaging
- Language-Reference
- BR-Model
- BTM-Model