blaise/README.adoc

264 lines
17 KiB
Plaintext
Raw Permalink Normal View History

2026-07-21 10:40:22 +03:00
ПРОГРАММА Привет;
НАЧАЛО
WriteLn('Привет от ВИРТ v0.12.0!');
WriteLn('Русские ключевые слова работают!');
КОНЕЦ.
2026-07-04 21:53:04 +03:00
= Компилятор Pascal Blaise
:icons: font
:source-highlighter: rouge
2026-07-04 21:53:04 +03:00
image:https://github.com/graemeg/blaise/actions/workflows/bootstrap.yml/badge.svg["Статус сборки", link="https://github.com/graemeg/blaise/actions/workflows/bootstrap.yml"]
2026-07-04 21:53:04 +03:00
**Pascal, который вы любите, переосмысленный для современной эпохи.**
2026-07-04 21:53:04 +03:00
Blaise — это компилятор Object Pascal нового поколения, созданный с нуля для устранения десятилетий устаревшего наследия. Он ставит во главу угла производительность разработчика, безопасность памяти и высокую производительность выполнения.
2026-07-04 21:53:04 +03:00
== ✨ Видение
2026-07-04 21:53:04 +03:00
Экосистема Object Pascal имеет два варианта: Embarcadero Delphi (проприетарный, ориентированный на Windows) и Free Pascal (открытый исходный код, но несущий 30 лет накопленной сложности — пять режимов языка, пять строковых типов и тысячи файлов включений).
2026-07-04 21:53:04 +03:00
Этот компилятор использует другой подход:
2026-07-04 21:53:04 +03:00
* *Один режим языка.* Без переключателей `{$mode}`; без поддержки устаревших диалектов.
* *Один строковый тип.* Строка UTF-8 с подсчётом ссылок и индексацией с 0. `RawBytes` для бинарных данных.
* *Одна модель памяти.* Автоматический подсчёт ссылок единообразно применяется к строкам, классам и интерфейсам. Нет разделения на ручное/автоматическое между `TObject` и `TInterfacedObject`; `[Weak]` разрывает циклы. `Free` сохранён как синоним для немедленного освобождения.
* *Чистые интерфейсы.* Без COM-идентификаторов GUID; диспетчеризация интерфейсов через таблицу виртуальных методов на этапе компиляции.
* *Реифицированные обобщения.* Мономорфизация на этапе компиляции — без стирания типов.
* *Современная система сборки.* PasBuild с `project.xml`; без makefile'ов.
* *Полноценный отладчик.* OPDF — формат отладки по умолчанию; DWARF не требуется.
2026-07-04 21:53:04 +03:00
См. link:docs/design.adoc[docs/design.adoc] для полной архитектуры и плана реализации.
2026-07-04 21:53:04 +03:00
Результат — современный кроссплатформенный компилятор Object Pascal, генерирующий нативный код через два бэкенда: прямой генератор кода для x86-64 (по умолчанию с v0.12.0) и https://c9x.me/compile/[QBE] (опционально через `--backend qbe`). Один режим языка, один строковый тип, интерфейсы без GUID, реифицированные обобщения и полноценная поддержка формата отладки https://github.com/graemeg/opdebugger[OPDF] — включая полноценную отладку на уровне исходного кода для инкрементально компилируемых многомодульных программ.
2026-07-04 21:53:04 +03:00
== 🚀 Статус проекта
2026-07-04 21:53:04 +03:00
* **Самохостинг:** Да. Blaise загружается и перекомпилирует себя с точностью байт-в-байт. FPC больше не требуется — весь инструментарий работает на одном Blaise.
* **Тестирование:** Более 3800 тестов и их число растёт (разработка через тестирование с первого дня). Набор тестов компилируется в Blaise.
* **Бэкенды:** Два бэкенда генерации кода — прямой нативный бэкенд для x86-64 (по умолчанию с v0.12.0) и QBE (опционально через `--backend qbe`). Оба проходят полный цикл фикспойнта и набор тестов.
* **Стандартная библиотека:** Растущая подключаемая стандартная библиотека — обобщённые коллекции, JSON (DOM + парсер + писатель), SHA-1 и Base64, GUID по RFC 4122, TCP-сокеты, WebSockets, минимальный HTTP/1.1 сервер и фреймворк для модульного тестирования `blaise.testing`.
[cols="1,3,1", options="header"]
|===
2026-07-04 21:53:04 +03:00
| Этап | Цель | Статус
| 1
2026-07-04 21:53:04 +03:00
| Конвейер загрузки — Hello World на Linux x86_64 через PasBuild
| Выполнен ✅
| 2
2026-07-04 21:53:04 +03:00
| Система типов — классы, записи, ARC, исключения
| Выполнен ✅
| 3
2026-07-04 21:53:04 +03:00
| Обобщения + интерфейсы без GUID
| Выполнен ✅
| 4
2026-07-04 21:53:04 +03:00
| Генерация отладочной информации OPDF
| Выполнен ✅
| 5
2026-07-04 21:53:04 +03:00
| Самохостинг
| Выполнен ✅
| 6
2026-07-04 21:53:04 +03:00
| Улучшения языка + расширение RTL и StdLib + исправление ошибок
| В процессе 🔄
2026-06-02 19:31:02 +03:00
| 7
2026-07-04 21:53:04 +03:00
| Паритет функций нативного бэкенда (бэкенд по умолчанию, внутренний ассемблер + компоновщик)
| Выполнен ✅
2026-06-02 19:31:02 +03:00
| 8
2026-07-04 21:53:04 +03:00
| Цели Windows + macOS ARM64
| Запланировано
2026-06-02 19:31:02 +03:00
| 9
2026-07-04 21:53:04 +03:00
| LSP + расширение для VS Code
| Запланировано
| 10
2026-07-04 21:53:04 +03:00
| Анализатор миграции для кодовых баз FPC/Delphi
| Запланировано
|===
2026-07-04 21:53:04 +03:00
== Что исключено из классического Pascal
[cols="1,3", options="header"]
|===
2026-07-04 21:53:04 +03:00
| Особенность | Причина удаления
| `ShortString`, `AnsiString`, `WideString`, `UnicodeString`
2026-07-04 21:53:04 +03:00
| Заменены единым строковым типом `string` в UTF-8 с подсчётом ссылок
2026-07-04 21:53:04 +03:00
| Оператор `with`
| Источник трудно диагностируемых ошибок разрешения символов; нарушает статический анализ
2026-07-04 21:53:04 +03:00
| Устаревшие типы `object`
| Используйте `record` (стек/значение) или `class` (куча/ссылка) вместо них
2026-07-04 21:53:04 +03:00
| Интерфейсные GUID в стиле COM
| Диспетчеризация интерфейсов через таблицу виртуальных методов на этапе компиляции; GUID — излишняя сложность
2026-07-04 21:53:04 +03:00
| Множественные режимы языка
| Один диалект, поддерживаемый хорошо, лучше, чем пять диалектов, поддерживаемых плохо
| `assign`, `reset`, `rewrite`, `blockread`
2026-07-04 21:53:04 +03:00
| Заменены RTL с потоковым вводом-выводом
2026-07-04 21:53:04 +03:00
| Разделение `TObject` и `TInterfacedObject`
| Единая модель классов с автоматическим подсчётом ссылок; `[Weak]` разрывает циклы
|===
2026-07-04 21:53:04 +03:00
== 📢 Сообщество
2026-07-04 21:53:04 +03:00
Базовая архитектура всё ещё дорабатывается, поэтому проект пока не принимает вклад в код. Обратная связь по дизайну языка, синтаксическим решениям и будущему направлению Blaise очень приветствуется — используйте вкладку https://github.com/graemeg/blaise/discussions[Discussions] на GitHub.
2026-07-04 21:53:04 +03:00
== Структура репозитория
2026-07-04 21:53:04 +03:00
Этот проект использует многомодульную структуру PasBuild. Каждый подкаталог с `project.xml` является независимым модулем; корневой `project.xml` является агрегатором.
....
2026-07-04 21:53:04 +03:00
project.xml Корневой агрегатор (packaging=pom)
2026-07-04 21:53:04 +03:00
├── compiler/ Бинарный файл компилятора (packaging=application)
│ ├── project.xml
│ └── src/
│ ├── main/pascal/ uLexer, uParser, uAST, blaise.codegen.qbe, blaise.codegen.native.*, ...
2026-07-04 21:53:04 +03:00
│ └── test/pascal/ Набор тестов (blaise.testing, компилируется Blaise)
2026-07-04 21:53:04 +03:00
├── runtime/ Время выполнения, всегда компонуется (packaging=library)
│ ├── project.xml
│ ├── Makefile
│ └── src/
2026-07-04 21:53:04 +03:00
│ ├── main/asm/ Ассемблер для платформы (setjmp, атомарные операции, UTF-8)
│ ├── main/pascal/ system.pas, blaise_str.pas, blaise_arc.pas, ...
2026-07-04 21:53:04 +03:00
│ └── test/pascal/ Тесты времени выполнения (punit, компилируются Blaise)
2026-07-04 21:53:04 +03:00
├── stdlib/ Стандартная библиотека — подключается через uses
│ ├── project.xml
│ └── src/
│ └── main/pascal/ sysutils.pas, classes.pas, math.pas, ...
├── tools/
2026-07-04 21:53:04 +03:00
│ └── migration-analyser/ Инструмент для отчётов по миграции из FPC/Delphi (packaging=application)
│ ├── project.xml зависит от модуля компилятора
│ └── src/
│ ├── main/pascal/
│ └── test/pascal/
2026-07-04 21:53:04 +03:00
├── vendor/qbe/ Исходный код бэкенда QBE (закреплённая версия, собирается из исходников)
└── docs/ Документы по дизайну и спецификации
....
2026-07-04 21:53:04 +03:00
PasBuild компилирует каждый модуль в свой подкаталог `target/`. Результаты сборки никогда не сохраняются в репозитории.
2026-07-04 21:53:04 +03:00
== Сборка
2026-07-04 21:53:04 +03:00
=== Предварительные требования
2026-07-04 21:53:04 +03:00
* Ранее выпущенный бинарный файл Blaise (см. `releases/`)
* https://github.com/graemeg/pasbuild[PasBuild]
2026-07-04 21:53:04 +03:00
* Компилятор C (`gcc` или `clang`) для сборки вендорского бэкенда QBE и компоновки
* GNU `make` для сборки времени выполнения
2026-07-04 21:53:04 +03:00
ПРИМЕЧАНИЕ: FPC *не* требуется. Blaise полностью самохостовый — каждый бинарник релиза компилирует следующую версию. Цепочка загрузки начинается с бинарника в `releases/`.
2026-07-04 21:53:04 +03:00
=== Загрузка из релиза
2026-07-04 21:53:04 +03:00
Сборка времени выполнения компилирует свои модули Pascal (`blaise_str.pas`, `blaise_arc.pas`, `blaise_sys.pas`) с использованием бинарника Blaise по пути `compiler/target/blaise`. В чистом виде этого бинарника ещё нет, поэтому бинарник релиза должен быть передан явно через переменную make `BLAISE`.
[source,shell]
----
2026-07-04 21:53:04 +03:00
# Определить новейший бинарник релиза (подставьте путь вместо $RELEASE).
RELEASE=$(ls -d releases/v*/ | sort -V | tail -1)blaise # например releases/v0.12.0/blaise
2026-07-04 21:53:04 +03:00
# 1. Собрать время выполнения с использованием бинарника релиза (BLAISE= предотвращает проблему курицы и яйца)
cd runtime && make BLAISE=../$RELEASE && make install && cd ..
2026-07-04 21:53:04 +03:00
# 2. Скомпилировать компилятор с использованием бинарника релиза (нативный бэкенд —
# по умолчанию с v0.12.0 — не требует внешнего ассемблера или QBE)
$RELEASE \
--source compiler/src/main/pascal/Blaise.pas \
--unit-path compiler/src/main/pascal \
--unit-path runtime/src/main/pascal \
--unit-path stdlib/src/main/pascal \
--output compiler/target/blaise
----
2026-07-04 21:53:04 +03:00
После появления `compiler/target/blaise` последующие пересборки RTL (`make && make install`) работают без переопределения.
2026-07-04 21:53:04 +03:00
Нативный бэкенд (по умолчанию) генерирует и компонует бинарник напрямую — без внешних инструментов. Для загрузки через опциональный бэкенд 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`.
2026-07-04 21:53:04 +03:00
=== Загрузка из разработческой версии
2026-07-04 21:53:04 +03:00
Эта процедура работает, пока последний бинарник релиза достаточно новый, чтобы скомпилировать текущий исходный код. Между релизами это перестаёт работать: как только коммит добавляет новую возможность в парсер, а последующий коммит использует её в среде выполнения/компиляторе, бинарник релиза больше не может собрать `master` напрямую.
2026-07-04 21:53:04 +03:00
`scripts/rolling-bootstrap.sh` пересобирает цепочку коммит за коммитом, начиная с последнего бинарника релиза и до проверенной ревизии, создавая рабочий `-pre` бинарник загрузки. См. link:scripts/BOOTSTRAP.adoc[scripts/BOOTSTRAP.adoc] для предварительных требований (размещение бинарника релиза в `releases/`) и использования.
2026-07-04 21:53:04 +03:00
=== Сборка через PasBuild
2026-07-04 21:53:04 +03:00
PasBuild может управлять полным циклом компиляции и тестирования с использованием бинарника Blaise:
[source,shell]
----
pasbuild compile -m blaise-compiler --compiler compiler/target/blaise
pasbuild test -m blaise-compiler --compiler compiler/target/blaise
----
2026-07-04 21:53:04 +03:00
=== Запуск тестов
[source,shell]
----
pasbuild test -m blaise-compiler --compiler compiler/target/blaise
----
2026-07-04 21:53:04 +03:00
=== Проверка фикспойнта самохостинга
2026-07-04 21:53:04 +03:00
После любого изменения компилятора проверьте, что компилятор воспроизводит себя:
[source,shell]
----
./scripts/fixpoint.sh
----
2026-07-04 21:53:04 +03:00
Это генерирует промежуточное представление (IR) для этапов 2 и 3 и подтверждает их идентичность.
2026-07-04 21:53:04 +03:00
=== Запуск компилятора
2026-07-04 21:53:04 +03:00
После сборки бинарник компилятора находится по пути `compiler/target/blaise`.
[source,shell]
----
2026-07-04 21:53:04 +03:00
# Скомпилировать однострочную программу (нативный бэкенд — по умолчанию, без внешних инструментов)
compiler/target/blaise --source Hello.pas --output Hello
2026-07-04 21:53:04 +03:00
# Скомпилировать через опциональный бэкенд QBE (генерирует QBE IR, собирается и компонуется отдельно)
compiler/target/blaise --source Hello.pas --backend qbe --emit-ir > Hello.ssa
vendor/qbe/qbe -o Hello.s Hello.ssa
gcc -o Hello Hello.s compiler/target/blaise_rtl.a
2026-07-04 21:53:04 +03:00
# Скомпилировать с путями поиска модулей
compiler/target/blaise --source MyApp.pas \
--unit-path src/units \
--emit-ir > MyApp.ssa
2026-07-04 21:53:04 +03:00
# Сгенерировать только QBE IR (полезно для отладки самого компилятора)
compiler/target/blaise --source Hello.pas --emit-ir
----
2026-07-04 21:53:04 +03:00
== Лицензия
2026-07-04 21:53:04 +03:00
Apache License v2.0 с исключением для библиотеки времени выполнения. См. link:LICENSE[LICENSE].
2026-07-04 21:54:44 +03:00
---