обновить ридми

This commit is contained in:
mzhoot 2026-07-04 21:53:04 +03:00
parent 8aec317ec9
commit f2c69b9d00

View file

@ -1,206 +1,185 @@
= Blaise Pascal Compiler ---
= Компилятор Pascal Blaise
:icons: font :icons: font
:source-highlighter: rouge :source-highlighter: rouge
image:https://github.com/graemeg/blaise/actions/workflows/bootstrap.yml/badge.svg["Build status", link="https://github.com/graemeg/blaise/actions/workflows/bootstrap.yml"] image:https://github.com/graemeg/blaise/actions/workflows/bootstrap.yml/badge.svg["Статус сборки", link="https://github.com/graemeg/blaise/actions/workflows/bootstrap.yml"]
**The Pascal you love, reimagined for the modern era.** **Pascal, который вы любите, переосмысленный для современной эпохи.**
Blaise is a next-generation Object Pascal compiler built from the ground up to eliminate decades of legacy baggage. It prioritizes developer productivity, memory safety, and high-performance execution. Blaise — это компилятор Object Pascal нового поколения, созданный с нуля для устранения десятилетий устаревшего наследия. Он ставит во главу угла производительность разработчика, безопасность памяти и высокую производительность выполнения.
== ✨ The Vision == ✨ Видение
The Object Pascal ecosystem has two options: Embarcadero Delphi (proprietary, Экосистема Object Pascal имеет два варианта: Embarcadero Delphi (проприетарный, ориентированный на Windows) и Free Pascal (открытый исходный код, но несущий 30 лет накопленной сложности — пять режимов языка, пять строковых типов и тысячи файлов включений).
Windows-first) and Free Pascal (open source but carrying 30 years of accumulated
complexity — five language modes, five string types, and thousands of include files).
This compiler takes a different approach: Этот компилятор использует другой подход:
* *One language mode.* No `{$mode}` switches; no legacy dialect support. * *Один режим языка.* Без переключателей `{$mode}`; без поддержки устаревших диалектов.
* *One string type.* UTF-8 reference-counted string and 0-based indexing. `RawBytes` for binary data. * *Один строковый тип.* Строка UTF-8 с подсчётом ссылок и индексацией с 0. `RawBytes` для бинарных данных.
* *One memory model.* Automatic reference counting applies uniformly to * *Одна модель памяти.* Автоматический подсчёт ссылок единообразно применяется к строкам, классам и интерфейсам. Нет разделения на ручное/автоматическое между `TObject` и `TInterfacedObject`; `[Weak]` разрывает циклы. `Free` сохранён как синоним для немедленного освобождения.
strings, classes, and interfaces. No manual/auto split between `TObject` * *Чистые интерфейсы.* Без COM-идентификаторов GUID; диспетчеризация интерфейсов через таблицу виртуальных методов на этапе компиляции.
and `TInterfacedObject`; `[Weak]` breaks cycles. `Free` is retained as a * *Реифицированные обобщения.* Мономорфизация на этапе компиляции — без стирания типов.
synonym for immediate release. * *Современная система сборки.* PasBuild с `project.xml`; без makefile'ов.
* *Clean interfaces.* No COM GUIDs; interface dispatch via compile-time vtable mapping. * *Полноценный отладчик.* OPDF — формат отладки по умолчанию; DWARF не требуется.
* *Reified generics.* Monomorphization at compile time — no type erasure.
* *Modern build system.* PasBuild with `project.xml`; no makefiles.
* *First-class debugger.* OPDF is the default debug format; DWARF is not required.
See link:docs/design.adoc[docs/design.adoc] for the full architecture and См. link:docs/design.adoc[docs/design.adoc] для полной архитектуры и плана реализации.
implementation plan.
The result — A modern, cross-platform Object Pascal compiler targeting native code Результат — современный кроссплатформенный компилятор Object Pascal, генерирующий нативный код через два бэкенда: прямой генератор кода для x86-64 (по умолчанию с v0.12.0) и https://c9x.me/compile/[QBE] (опционально через `--backend qbe`). Один режим языка, один строковый тип, интерфейсы без GUID, реифицированные обобщения и полноценная поддержка формата отладки https://github.com/graemeg/opdebugger[OPDF] — включая полноценную отладку на уровне исходного кода для инкрементально компилируемых многомодульных программ.
via two backends: a direct native x86-64 code generator (the default since
v0.12.0) and https://c9x.me/compile/[QBE] (now opt-in via `--backend qbe`).
Single language mode, single string type, zero-GUID interfaces, reified
generics, and first-class
https://github.com/graemeg/opdebugger[OPDF] debug format support — including
full source-level debugging of incrementally-compiled multi-unit programs.
== 🚀 Project Status == 🚀 Статус проекта
* **Self-Hosting:** Yes. Blaise bootstraps and recompiles itself with byte-for-byte fixpoint. FPC is no longer required — the entire toolchain runs on Blaise alone. * **Самохостинг:** Да. Blaise загружается и перекомпилирует себя с точностью байт-в-байт. FPC больше не требуется — весь инструментарий работает на одном Blaise.
* **Testing:** 3800+ tests and growing (Test-Driven Development from day one). The test suite itself compiles under Blaise. * **Тестирование:** Более 3800 тестов и их число растёт (разработка через тестирование с первого дня). Набор тестов компилируется в Blaise.
* **Backends:** Two code-generation backends — a direct native x86-64 backend (the default since v0.12.0) and QBE (opt-in via `--backend qbe`). Both pass the full fixpoint and test suite. * **Бэкенды:** Два бэкенда генерации кода — прямой нативный бэкенд для x86-64 (по умолчанию с v0.12.0) и QBE (опционально через `--backend qbe`). Оба проходят полный цикл фикспойнта и набор тестов.
* **Standard library:** A growing opt-in stdlib — generics collections, JSON (DOM + parser + writer), SHA-1 and Base64, RFC 4122 GUIDs, TCP sockets, WebSockets, a minimal HTTP/1.1 server, and a `blaise.testing` unit-test framework. * **Стандартная библиотека:** Растущая подключаемая стандартная библиотека — обобщённые коллекции, JSON (DOM + парсер + писатель), SHA-1 и Base64, GUID по RFC 4122, TCP-сокеты, WebSockets, минимальный HTTP/1.1 сервер и фреймворк для модульного тестирования `blaise.testing`.
[cols="1,3,1", options="header"] [cols="1,3,1", options="header"]
|=== |===
| Phase | Goal | Status | Этап | Цель | Статус
| 1 | 1
| Bootstrap pipeline — Hello World on Linux x86_64 via PasBuild | Конвейер загрузки — Hello World на Linux x86_64 через PasBuild
| Complete ✅ | Выполнен ✅
| 2 | 2
| Type system — classes, records, ARC, exceptions | Система типов — классы, записи, ARC, исключения
| Complete ✅ | Выполнен ✅
| 3 | 3
| Generics + zero-GUID interfaces | Обобщения + интерфейсы без GUID
| Complete ✅ | Выполнен ✅
| 4 | 4
| OPDF debug info emission | Генерация отладочной информации OPDF
| Complete ✅ | Выполнен ✅
| 5 | 5
| Self-hosting | Самохостинг
| Complete ✅ | Выполнен ✅
| 6 | 6
| Language improvements + expand RTL & StdLib + bug fixing | Улучшения языка + расширение RTL и StdLib + исправление ошибок
| Ongoing 🔄 | В процессе 🔄
| 7 | 7
| Native backend feature parity (default backend, internal assembler + linker) | Паритет функций нативного бэкенда (бэкенд по умолчанию, внутренний ассемблер + компоновщик)
| Complete ✅ | Выполнен ✅
| 8 | 8
| Windows + macOS ARM64 targets | Цели Windows + macOS ARM64
| Planned | Запланировано
| 9 | 9
| LSP + VS Code extension | LSP + расширение для VS Code
| Planned | Запланировано
| 10 | 10
| Migration analyser for FPC/Delphi codebases | Анализатор миграции для кодовых баз FPC/Delphi
| Planned | Запланировано
|=== |===
== What Is Dropped From Classic Pascal == Что исключено из классического Pascal
[cols="1,3", options="header"] [cols="1,3", options="header"]
|=== |===
| Feature | Reason for removal | Особенность | Причина удаления
| `ShortString`, `AnsiString`, `WideString`, `UnicodeString` | `ShortString`, `AnsiString`, `WideString`, `UnicodeString`
| Replaced by a single UTF-8 reference-counted `string` type | Заменены единым строковым типом `string` в UTF-8 с подсчётом ссылок
| `with` statement | Оператор `with`
| Source of hard-to-diagnose symbol resolution bugs; breaks static analysis | Источник трудно диагностируемых ошибок разрешения символов; нарушает статический анализ
| Old-style `object` types | Устаревшие типы `object`
| Use `record` (stack/value) or `class` (heap/reference) instead | Используйте `record` (стек/значение) или `class` (куча/ссылка) вместо них
| COM-style interface GUIDs | Интерфейсные GUID в стиле COM
| Interface dispatch via compile-time vtable; GUIDs are unnecessary complexity | Диспетчеризация интерфейсов через таблицу виртуальных методов на этапе компиляции; GUID — излишняя сложность
| Multiple language modes | Множественные режимы языка
| One dialect, maintained well, beats five dialects maintained poorly | Один диалект, поддерживаемый хорошо, лучше, чем пять диалектов, поддерживаемых плохо
| `assign`, `reset`, `rewrite`, `blockread` | `assign`, `reset`, `rewrite`, `blockread`
| Replaced by a stream-based I/O RTL | Заменены RTL с потоковым вводом-выводом
| `TObject` vs `TInterfacedObject` split | Разделение `TObject` и `TInterfacedObject`
| One unified class model under automatic reference counting; `[Weak]` | Единая модель классов с автоматическим подсчётом ссылок; `[Weak]` разрывает циклы
breaks cycles
|=== |===
== 📢 Community == 📢 Сообщество
The core architecture is still being finalised, so the project is not yet Базовая архитектура всё ещё дорабатывается, поэтому проект пока не принимает вклад в код. Обратная связь по дизайну языка, синтаксическим решениям и будущему направлению Blaise очень приветствуется — используйте вкладку https://github.com/graemeg/blaise/discussions[Discussions] на GitHub.
accepting code contributions. Feedback on language design, syntax choices, and
the future direction of Blaise is very welcome — please use the
https://github.com/graemeg/blaise/discussions[Discussions] tab on GitHub.
== Repository Layout == Структура репозитория
This project uses PasBuild's multi-module layout. Each subdirectory with a Этот проект использует многомодульную структуру PasBuild. Каждый подкаталог с `project.xml` является независимым модулем; корневой `project.xml` является агрегатором.
`project.xml` is an independent module; the root `project.xml` is the aggregator.
.... ....
project.xml Root aggregator (packaging=pom) project.xml Корневой агрегатор (packaging=pom)
│ │
├── compiler/ The compiler binary (packaging=application) ├── compiler/ Бинарный файл компилятора (packaging=application)
│ ├── project.xml │ ├── project.xml
│ └── src/ │ └── src/
│ ├── main/pascal/ uLexer, uParser, uAST, blaise.codegen.qbe, blaise.codegen.native.*, ... │ ├── main/pascal/ uLexer, uParser, uAST, blaise.codegen.qbe, blaise.codegen.native.*, ...
│ └── test/pascal/ Test suite (blaise.testing, compiled by Blaise) │ └── test/pascal/ Набор тестов (blaise.testing, компилируется Blaise)
│ │
├── runtime/ Always-linked runtime (packaging=library) ├── runtime/ Время выполнения, всегда компонуется (packaging=library)
│ ├── project.xml │ ├── project.xml
│ ├── Makefile │ ├── Makefile
│ └── src/ │ └── src/
│ ├── main/asm/ Platform assembly (setjmp, atomics, UTF-8) │ ├── main/asm/ Ассемблер для платформы (setjmp, атомарные операции, UTF-8)
│ ├── main/pascal/ system.pas, blaise_str.pas, blaise_arc.pas, ... │ ├── main/pascal/ system.pas, blaise_str.pas, blaise_arc.pas, ...
│ └── test/pascal/ Runtime tests (punit, compiled by Blaise) │ └── test/pascal/ Тесты времени выполнения (punit, компилируются Blaise)
│ │
├── stdlib/ Standard library — opt-in via uses clause ├── stdlib/ Стандартная библиотека — подключается через uses
│ ├── project.xml │ ├── project.xml
│ └── src/ │ └── src/
│ └── main/pascal/ sysutils.pas, classes.pas, math.pas, ... │ └── main/pascal/ sysutils.pas, classes.pas, math.pas, ...
│ │
├── tools/ ├── tools/
│ └── migration-analyser/ FPC/Delphi migration report tool (packaging=application) │ └── migration-analyser/ Инструмент для отчётов по миграции из FPC/Delphi (packaging=application)
│ ├── project.xml depends on compiler module │ ├── project.xml зависит от модуля компилятора
│ └── src/ │ └── src/
│ ├── main/pascal/ │ ├── main/pascal/
│ └── test/pascal/ │ └── test/pascal/
│ │
├── vendor/qbe/ Vendored QBE backend source (pinned, built from source) ├── vendor/qbe/ Исходный код бэкенда QBE (закреплённая версия, собирается из исходников)
└── docs/ Design documents and specifications └── docs/ Документы по дизайну и спецификации
.... ....
PasBuild compiles each module to its own `target/` subdirectory. Build output is PasBuild компилирует каждый модуль в свой подкаталог `target/`. Результаты сборки никогда не сохраняются в репозитории.
never committed to the repository.
== Building == Сборка
=== Prerequisites === Предварительные требования
* A previously released Blaise binary (see `releases/`) * Ранее выпущенный бинарный файл Blaise (см. `releases/`)
* https://github.com/graemeg/pasbuild[PasBuild] * https://github.com/graemeg/pasbuild[PasBuild]
* A C compiler (`gcc` or `clang`) for building the vendored QBE backend and linking * Компилятор C (`gcc` или `clang`) для сборки вендорского бэкенда QBE и компоновки
* GNU `make` for the runtime build * GNU `make` для сборки времени выполнения
NOTE: FPC is *not* required. Blaise is fully self-hosting — each release binary ПРИМЕЧАНИЕ: FPC *не* требуется. Blaise полностью самохостовый — каждый бинарник релиза компилирует следующую версию. Цепочка загрузки начинается с бинарника в `releases/`.
compiles the next version. The bootstrap chain starts from the binary in
`releases/`.
=== Bootstrap from a release === Загрузка из релиза
The runtime build compiles its Pascal units (`blaise_str.pas`, `blaise_arc.pas`, Сборка времени выполнения компилирует свои модули Pascal (`blaise_str.pas`, `blaise_arc.pas`, `blaise_sys.pas`) с использованием бинарника Blaise по пути `compiler/target/blaise`. В чистом виде этого бинарника ещё нет, поэтому бинарник релиза должен быть передан явно через переменную make `BLAISE`.
`blaise_sys.pas`) using the Blaise binary at `compiler/target/blaise`. On a
clean checkout that binary does not exist yet, so the release binary must be
passed explicitly via the `BLAISE` make variable.
[source,shell] [source,shell]
---- ----
# Resolve the newest release binary (substitute the path below for $RELEASE). # Определить новейший бинарник релиза (подставьте путь вместо $RELEASE).
RELEASE=$(ls -d releases/v*/ | sort -V | tail -1)blaise # e.g. releases/v0.12.0/blaise RELEASE=$(ls -d releases/v*/ | sort -V | tail -1)blaise # например releases/v0.12.0/blaise
# 1. Build the runtime using the release binary (BLAISE= avoids chicken-and-egg) # 1. Собрать время выполнения с использованием бинарника релиза (BLAISE= предотвращает проблему курицы и яйца)
cd runtime && make BLAISE=../$RELEASE && make install && cd .. cd runtime && make BLAISE=../$RELEASE && make install && cd ..
# 2. Compile the compiler using the release binary (native backend — the # 2. Скомпилировать компилятор с использованием бинарника релиза (нативный бэкенд —
# default since v0.12.0 — needs no external assembler or QBE) # по умолчанию с v0.12.0 — не требует внешнего ассемблера или QBE)
$RELEASE \ $RELEASE \
--source compiler/src/main/pascal/Blaise.pas \ --source compiler/src/main/pascal/Blaise.pas \
--unit-path compiler/src/main/pascal \ --unit-path compiler/src/main/pascal \
@ -209,30 +188,19 @@ $RELEASE \
--output compiler/target/blaise --output compiler/target/blaise
---- ----
Once `compiler/target/blaise` exists, subsequent RTL rebuilds (`make && make install`) После появления `compiler/target/blaise` последующие пересборки RTL (`make && make install`) работают без переопределения.
work without the override.
The native backend (default) emits and links a binary directly — no external Нативный бэкенд (по умолчанию) генерирует и компонует бинарник напрямую — без внешних инструментов. Для загрузки через опциональный бэкенд QBE вместо этого соберите вендорский QBE один раз (`cd vendor/qbe && make`), добавьте `--backend qbe --emit-ir > /tmp/blaise.ssa` к шагу 2, затем `vendor/qbe/qbe -o /tmp/blaise.s /tmp/blaise.ssa` и `gcc -o compiler/target/blaise /tmp/blaise.s compiler/target/blaise_rtl.a`.
tools. To bootstrap via the opt-in QBE backend instead, build the vendored QBE
once (`cd vendor/qbe && make`), add `--backend qbe --emit-ir > /tmp/blaise.ssa`
to step 2, then `vendor/qbe/qbe -o /tmp/blaise.s /tmp/blaise.ssa` and
`gcc -o compiler/target/blaise /tmp/blaise.s compiler/target/blaise_rtl.a`.
=== Bootstrap a development checkout === Загрузка из разработческой версии
The procedure above works while the latest release binary is new enough to Эта процедура работает, пока последний бинарник релиза достаточно новый, чтобы скомпилировать текущий исходный код. Между релизами это перестаёт работать: как только коммит добавляет новую возможность в парсер, а последующий коммит использует её в среде выполнения/компиляторе, бинарник релиза больше не может собрать `master` напрямую.
compile the current source. Between releases that ceases to hold: once a commit
teaches the parser a new feature and a later commit uses it in the
runtime/compiler, the release binary can no longer build `master` directly.
`scripts/rolling-bootstrap.sh` rebuilds the chain commit-by-commit from the last `scripts/rolling-bootstrap.sh` пересобирает цепочку коммит за коммитом, начиная с последнего бинарника релиза и до проверенной ревизии, создавая рабочий `-pre` бинарник загрузки. См. link:scripts/BOOTSTRAP.adoc[scripts/BOOTSTRAP.adoc] для предварительных требований (размещение бинарника релиза в `releases/`) и использования.
release binary up to the checked-out revision, producing a working `-pre`
bootstrap binary. See link:scripts/BOOTSTRAP.adoc[scripts/BOOTSTRAP.adoc] for the
prerequisite (placing the release binary under `releases/`) and usage.
=== Build via PasBuild === Сборка через PasBuild
PasBuild can drive the full compile and test cycle using a Blaise binary: PasBuild может управлять полным циклом компиляции и тестирования с использованием бинарника Blaise:
[source,shell] [source,shell]
---- ----
@ -240,51 +208,50 @@ pasbuild compile -m blaise-compiler --compiler compiler/target/blaise
pasbuild test -m blaise-compiler --compiler compiler/target/blaise pasbuild test -m blaise-compiler --compiler compiler/target/blaise
---- ----
=== Run tests === Запуск тестов
[source,shell] [source,shell]
---- ----
pasbuild test -m blaise-compiler --compiler compiler/target/blaise pasbuild test -m blaise-compiler --compiler compiler/target/blaise
---- ----
=== Verify self-hosting fixpoint === Проверка фикспойнта самохостинга
After any compiler change, verify that the compiler reproduces itself: После любого изменения компилятора проверьте, что компилятор воспроизводит себя:
[source,shell] [source,shell]
---- ----
./scripts/fixpoint.sh ./scripts/fixpoint.sh
---- ----
This generates stage-2 and stage-3 IR and confirms they are identical. Это генерирует промежуточное представление (IR) для этапов 2 и 3 и подтверждает их идентичность.
=== Running the compiler === Запуск компилятора
Once built, the compiler binary is at `compiler/target/blaise`. После сборки бинарник компилятора находится по пути `compiler/target/blaise`.
[source,shell] [source,shell]
---- ----
# Compile a single-file program (native backend — default, no external tools) # Скомпилировать однострочную программу (нативный бэкенд — по умолчанию, без внешних инструментов)
compiler/target/blaise --source Hello.pas --output Hello compiler/target/blaise --source Hello.pas --output Hello
# Compile via the opt-in QBE backend (emits QBE IR, assembled + linked separately) # Скомпилировать через опциональный бэкенд QBE (генерирует QBE IR, собирается и компонуется отдельно)
compiler/target/blaise --source Hello.pas --backend qbe --emit-ir > Hello.ssa compiler/target/blaise --source Hello.pas --backend qbe --emit-ir > Hello.ssa
vendor/qbe/qbe -o Hello.s Hello.ssa vendor/qbe/qbe -o Hello.s Hello.ssa
gcc -o Hello Hello.s compiler/target/blaise_rtl.a gcc -o Hello Hello.s compiler/target/blaise_rtl.a
# Compile with unit search paths # Скомпилировать с путями поиска модулей
compiler/target/blaise --source MyApp.pas \ compiler/target/blaise --source MyApp.pas \
--unit-path src/units \ --unit-path src/units \
--emit-ir > MyApp.ssa --emit-ir > MyApp.ssa
# Emit QBE IR only (useful for debugging the compiler itself) # Сгенерировать только QBE IR (полезно для отладки самого компилятора)
compiler/target/blaise --source Hello.pas --emit-ir compiler/target/blaise --source Hello.pas --emit-ir
---- ----
== Licence == Лицензия
Apache License v2.0 with Runtime Library Exception. See link:LICENSE[LICENSE]. Apache License v2.0 с исключением для библиотеки времени выполнения. См. link:LICENSE[LICENSE].
--- ---
*Built with ❤️ for the Pascal community by Graeme.*