ПРОГРАММА Привет;
НАЧАЛО
  WriteLn('Привет от ВИРТ v0.12.0!');
  WriteLn('Русские ключевые слова работают!');
КОНЕЦ.



= Компилятор Pascal Blaise
:icons: font
:source-highlighter: rouge

image:https://github.com/graemeg/blaise/actions/workflows/bootstrap.yml/badge.svg["Статус сборки", link="https://github.com/graemeg/blaise/actions/workflows/bootstrap.yml"]

**Pascal, который вы любите, переосмысленный для современной эпохи.**

Blaise — это компилятор Object Pascal нового поколения, созданный с нуля для устранения десятилетий устаревшего наследия. Он ставит во главу угла производительность разработчика, безопасность памяти и высокую производительность выполнения.


== ✨ Видение

Экосистема Object Pascal имеет два варианта: Embarcadero Delphi (проприетарный, ориентированный на Windows) и Free Pascal (открытый исходный код, но несущий 30 лет накопленной сложности — пять режимов языка, пять строковых типов и тысячи файлов включений).

Этот компилятор использует другой подход:

* *Один режим языка.* Без переключателей `{$mode}`; без поддержки устаревших диалектов.
* *Один строковый тип.* Строка UTF-8 с подсчётом ссылок и индексацией с 0. `RawBytes` для бинарных данных.
* *Одна модель памяти.* Автоматический подсчёт ссылок единообразно применяется к строкам, классам и интерфейсам. Нет разделения на ручное/автоматическое между `TObject` и `TInterfacedObject`; `[Weak]` разрывает циклы. `Free` сохранён как синоним для немедленного освобождения.
* *Чистые интерфейсы.* Без COM-идентификаторов GUID; диспетчеризация интерфейсов через таблицу виртуальных методов на этапе компиляции.
* *Реифицированные обобщения.* Мономорфизация на этапе компиляции — без стирания типов.
* *Современная система сборки.* PasBuild с `project.xml`; без makefile'ов.
* *Полноценный отладчик.* OPDF — формат отладки по умолчанию; DWARF не требуется.

См. link:docs/design.adoc[docs/design.adoc] для полной архитектуры и плана реализации.

Результат — современный кроссплатформенный компилятор Object Pascal, генерирующий нативный код через два бэкенда: прямой генератор кода для x86-64 (по умолчанию с v0.12.0) и https://c9x.me/compile/[QBE] (опционально через `--backend qbe`). Один режим языка, один строковый тип, интерфейсы без GUID, реифицированные обобщения и полноценная поддержка формата отладки https://github.com/graemeg/opdebugger[OPDF] — включая полноценную отладку на уровне исходного кода для инкрементально компилируемых многомодульных программ.


== 🚀 Статус проекта

* **Самохостинг:** Да. 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"]
|===
| Этап | Цель | Статус

| 1
| Конвейер загрузки — Hello World на Linux x86_64 через PasBuild
| Выполнен ✅

| 2
| Система типов — классы, записи, ARC, исключения
| Выполнен ✅

| 3
| Обобщения + интерфейсы без GUID
| Выполнен ✅

| 4
| Генерация отладочной информации OPDF
| Выполнен ✅

| 5
| Самохостинг
| Выполнен ✅

| 6
| Улучшения языка + расширение RTL и StdLib + исправление ошибок
| В процессе 🔄

| 7
| Паритет функций нативного бэкенда (бэкенд по умолчанию, внутренний ассемблер + компоновщик)
| Выполнен ✅

| 8
| Цели Windows + macOS ARM64
| Запланировано

| 9
| LSP + расширение для VS Code
| Запланировано

| 10
| Анализатор миграции для кодовых баз FPC/Delphi
| Запланировано
|===

== Что исключено из классического Pascal

[cols="1,3", options="header"]
|===
| Особенность | Причина удаления

| `ShortString`, `AnsiString`, `WideString`, `UnicodeString`
| Заменены единым строковым типом `string` в UTF-8 с подсчётом ссылок

| Оператор `with`
| Источник трудно диагностируемых ошибок разрешения символов; нарушает статический анализ

| Устаревшие типы `object`
| Используйте `record` (стек/значение) или `class` (куча/ссылка) вместо них

| Интерфейсные GUID в стиле COM
| Диспетчеризация интерфейсов через таблицу виртуальных методов на этапе компиляции; GUID — излишняя сложность

| Множественные режимы языка
| Один диалект, поддерживаемый хорошо, лучше, чем пять диалектов, поддерживаемых плохо

| `assign`, `reset`, `rewrite`, `blockread`
| Заменены RTL с потоковым вводом-выводом

| Разделение `TObject` и `TInterfacedObject`
| Единая модель классов с автоматическим подсчётом ссылок; `[Weak]` разрывает циклы
|===

== 📢 Сообщество

Базовая архитектура всё ещё дорабатывается, поэтому проект пока не принимает вклад в код. Обратная связь по дизайну языка, синтаксическим решениям и будущему направлению Blaise очень приветствуется — используйте вкладку https://github.com/graemeg/blaise/discussions[Discussions] на GitHub.


== Структура репозитория

Этот проект использует многомодульную структуру PasBuild. Каждый подкаталог с `project.xml` является независимым модулем; корневой `project.xml` является агрегатором.

....
project.xml                       Корневой агрегатор (packaging=pom)
│
├── compiler/                     Бинарный файл компилятора (packaging=application)
│   ├── project.xml
│   └── src/
│       ├── main/pascal/          uLexer, uParser, uAST, blaise.codegen.qbe, blaise.codegen.native.*, ...
│       └── test/pascal/          Набор тестов (blaise.testing, компилируется Blaise)
│
├── runtime/                      Время выполнения, всегда компонуется (packaging=library)
│   ├── project.xml
│   ├── Makefile
│   └── src/
│       ├── main/asm/             Ассемблер для платформы (setjmp, атомарные операции, UTF-8)
│       ├── main/pascal/          system.pas, blaise_str.pas, blaise_arc.pas, ...
│       └── test/pascal/          Тесты времени выполнения (punit, компилируются Blaise)
│
├── stdlib/                       Стандартная библиотека — подключается через uses
│   ├── project.xml
│   └── src/
│       └── main/pascal/          sysutils.pas, classes.pas, math.pas, ...
│
├── tools/
│   └── migration-analyser/       Инструмент для отчётов по миграции из FPC/Delphi (packaging=application)
│       ├── project.xml           зависит от модуля компилятора
│       └── src/
│           ├── main/pascal/
│           └── test/pascal/
│
├── vendor/qbe/                   Исходный код бэкенда QBE (закреплённая версия, собирается из исходников)
└── docs/                         Документы по дизайну и спецификации
....

PasBuild компилирует каждый модуль в свой подкаталог `target/`. Результаты сборки никогда не сохраняются в репозитории.

== Сборка

=== Предварительные требования

* Ранее выпущенный бинарный файл Blaise (см. `releases/`)
* https://github.com/graemeg/pasbuild[PasBuild]
* Компилятор C (`gcc` или `clang`) для сборки вендорского бэкенда QBE и компоновки
* GNU `make` для сборки времени выполнения

ПРИМЕЧАНИЕ: FPC *не* требуется. Blaise полностью самохостовый — каждый бинарник релиза компилирует следующую версию. Цепочка загрузки начинается с бинарника в `releases/`.

=== Загрузка из релиза

Сборка времени выполнения компилирует свои модули Pascal (`blaise_str.pas`, `blaise_arc.pas`, `blaise_sys.pas`) с использованием бинарника Blaise по пути `compiler/target/blaise`. В чистом виде этого бинарника ещё нет, поэтому бинарник релиза должен быть передан явно через переменную make `BLAISE`.

[source,shell]
----
# Определить новейший бинарник релиза (подставьте путь вместо $RELEASE).
RELEASE=$(ls -d releases/v*/ | sort -V | tail -1)blaise   # например releases/v0.12.0/blaise

# 1. Собрать время выполнения с использованием бинарника релиза (BLAISE= предотвращает проблему курицы и яйца)
cd runtime && make BLAISE=../$RELEASE && make install && cd ..

# 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
----

После появления `compiler/target/blaise` последующие пересборки RTL (`make && make install`) работают без переопределения.

Нативный бэкенд (по умолчанию) генерирует и компонует бинарник напрямую — без внешних инструментов. Для загрузки через опциональный бэкенд 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`.

=== Загрузка из разработческой версии

Эта процедура работает, пока последний бинарник релиза достаточно новый, чтобы скомпилировать текущий исходный код. Между релизами это перестаёт работать: как только коммит добавляет новую возможность в парсер, а последующий коммит использует её в среде выполнения/компиляторе, бинарник релиза больше не может собрать `master` напрямую.

`scripts/rolling-bootstrap.sh` пересобирает цепочку коммит за коммитом, начиная с последнего бинарника релиза и до проверенной ревизии, создавая рабочий `-pre` бинарник загрузки. См. link:scripts/BOOTSTRAP.adoc[scripts/BOOTSTRAP.adoc] для предварительных требований (размещение бинарника релиза в `releases/`) и использования.

=== Сборка через PasBuild

PasBuild может управлять полным циклом компиляции и тестирования с использованием бинарника Blaise:

[source,shell]
----
pasbuild compile -m blaise-compiler --compiler compiler/target/blaise
pasbuild test -m blaise-compiler --compiler compiler/target/blaise
----

=== Запуск тестов

[source,shell]
----
pasbuild test -m blaise-compiler --compiler compiler/target/blaise
----

=== Проверка фикспойнта самохостинга

После любого изменения компилятора проверьте, что компилятор воспроизводит себя:

[source,shell]
----
./scripts/fixpoint.sh
----

Это генерирует промежуточное представление (IR) для этапов 2 и 3 и подтверждает их идентичность.

=== Запуск компилятора

После сборки бинарник компилятора находится по пути `compiler/target/blaise`.

[source,shell]
----
# Скомпилировать однострочную программу (нативный бэкенд — по умолчанию, без внешних инструментов)
compiler/target/blaise --source Hello.pas --output Hello

# Скомпилировать через опциональный бэкенд 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

# Скомпилировать с путями поиска модулей
compiler/target/blaise --source MyApp.pas \
  --unit-path src/units \
  --emit-ir > MyApp.ssa

# Сгенерировать только QBE IR (полезно для отладки самого компилятора)
compiler/target/blaise --source Hello.pas --emit-ir
----

== Лицензия

Apache License v2.0 с исключением для библиотеки времени выполнения. См. link:LICENSE[LICENSE].


---
