-
Notifications
You must be signed in to change notification settings - Fork 0
Advanced ru
English | 中文 | Русский | Español | Português | 繁體中文 | Deutsch
Мастер-класс: типизированные умные ссылки, вызов нативных библиотек C, управление памятью, производительность, аннотации как инструмент проектирования и полноценный практический проект.
Умная ссылка — это типизированное значение, указывающее на lvalue. Она объявляется как право доступа × уровень × базовый тип:
&<permission> <follow> <base type> <name> = &<lvalue>;
-
Права доступа (7 стеков):
rчтение,wзапись,mперемещение (указателя),rw,rm,wm,rwm. -
Уровни (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 ссылка — это перемещающийся указатель (как a++ в C):
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 (тело, выглядящее как read-only, можно объявить методом записи, и наоборот). -
@onlyreadотказывает в любом вызове методов записи на потоке. -
@unforkотказывает во всех путях разветвления, включаяnewна классе@unfork.
Поток может привязаться к разделяемой библиотеке:
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 /
платформенный шим обрабатывает различия dlopen/LoadLibrary, так что это
работает и в Windows.
- Интерпретатор использует арену на основе блоков — выделения никогда не перемещаются.
- Ограничение по умолчанию: 256 МиБ в режиме интерпретации;
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. Требуется zig >= 0.14 в PATH.
Внутреннее устройство: загрузчик динамически слинкован с разделяемой средой
выполнения в lib/ (rpath $ORIGIN/../lib); Windows использует bio.bat для
установки PATH. Нити используют ucontext на POSIX и Win32 fibers в
Windows; бинарные библиотеки подключаются через 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— дамп потока токенов лексера. - Сообщения об отказах — первоклассные:
cause exprпоказывает точно, почему запрос не удался. - Собирайте с
make PROFILE=sanitizeдля сборок ASan + UBSan.
- Введение — основы и управляющий поток.
- Продвинутый — потоки, классы, проекты, нити.
- Packaging — форматы и релизные деревья.
-
Примеры — 15
прокомментированных программ, покрывающих все возможности (особенно
11-smart-refs.bio,14-binary-lib.bio,15-annotations.bio).
- Home
- Beginner — first steps
- Intermediate — real usage
- Advanced — masterclass
- Build & Run
- Packaging
- Language-Reference
- BR-Model
- BTM-Model