blaise/README.adoc

196 lines
5.5 KiB
Plaintext
Raw Normal View History

= Blaise
:toc: left
:toclevels: 2
:icons: font
:source-highlighter: rouge
A modern, cross-platform Object Pascal compiler targeting native code via
https://c9x.me/compile/[QBE] (and eventually LLVM). Single language mode,
single string type, zero-GUID interfaces, reified generics, and first-class
https://github.com/graemeg/opdebugger[OPDF] debug format support.
Bootstrapped with https://www.freepascal.org/[Free Pascal Compiler].
Built with https://github.com/graemeg/pasbuild[PasBuild].
Licensed under the BSD 3-Clause licence.
== Design Philosophy
The Object Pascal ecosystem has two options: Embarcadero Delphi (proprietary,
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.
* *One string type.* UTF-8 reference-counted string. `RawBytes` for binary data.
* *One memory model.* Automatic reference counting applies uniformly to
strings, classes, and interfaces. No manual/auto split between `TObject`
and `TInterfacedObject`; `[Weak]` breaks cycles. `Free` is retained as a
synonym for immediate release.
* *Clean interfaces.* No COM GUIDs; interface dispatch via compile-time vtable mapping.
* *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
implementation plan.
== Repository Layout
This project uses PasBuild's multi-module layout. Each subdirectory with a
`project.xml` is an independent module; the root `project.xml` is the aggregator.
....
project.xml Root aggregator (packaging=pom)
├── compiler/ The compiler binary (packaging=application)
│ ├── project.xml
│ └── src/
│ ├── main/pascal/ uLexer, uParser, uAST, uCodeGenQBE, ...
│ └── test/pascal/ FPTest test suite for compiler units
├── rtl/ Runtime library (packaging=library)
│ ├── project.xml
│ └── src/
│ ├── main/pascal/ System.pas, SysUtils.pas, Classes.pas, ...
│ └── test/pascal/ FPTest test suite for RTL units
├── tools/
│ └── migration-analyser/ FPC/Delphi migration report tool (packaging=application)
│ ├── project.xml depends on compiler module
│ └── src/
│ ├── main/pascal/
│ └── test/pascal/
├── vendor/qbe/ Vendored QBE backend source (pinned, built from source)
└── docs/ Design documents and specifications
....
PasBuild compiles each module to its own `target/` subdirectory. Build output is
never committed to the repository.
== Status
[cols="1,3,1", options="header"]
|===
| Phase | Goal | Status
| 1
| Bootstrap pipeline — Hello World on Linux x86_64 via PasBuild
2026-04-21 23:49:22 +03:00
| Complete
| 2
| Type system — classes, records, ARC, exceptions
2026-04-21 23:49:22 +03:00
| Complete
| 3
| Generics + zero-GUID interfaces
| Complete
| 4
| OPDF debug info emission
| Planned
| 5
2026-04-21 23:49:22 +03:00
| Self-hosting + LLVM + Windows + macOS ARM64
| Planned
| 6
| LSP + VS Code extension
| Planned
| 7
| Migration analyser for FPC/Delphi codebases
| Planned
|===
== Building
=== Prerequisites
* Free Pascal Compiler 3.2.2 or later (stable; 3.3.x development snapshots are not required)
* https://github.com/graemeg/pasbuild[PasBuild]
* A C compiler (`gcc` or `clang`) for building the vendored QBE backend
* GNU `ld` or `lld` (Linux); `ld` (macOS)
=== Build all modules
[source,shell]
----
pasbuild compile
----
PasBuild resolves the module dependency order automatically and compiles
`rtl` → `compiler` → `tools/migration-analyser`.
=== Build with a profile
[source,shell]
----
pasbuild compile -p debug # includes -g -gl -Criot -gh
pasbuild compile -p release # includes -O2 -CX -XX -Xs
----
=== Run tests
[source,shell]
----
pasbuild test
----
=== Build a single module
[source,shell]
----
pasbuild compile -m blaise-compiler
----
=== Running the compiler
Once built, the compiler binary is at `compiler/target/blaise`.
[source,shell]
----
# Compile a single file
compiler/target/blaise --source Hello.pas --output Hello
# Compile via project.xml
compiler/target/blaise --project project.xml --config debug --output myapp
# Emit QBE IR (useful for debugging the compiler itself)
compiler/target/blaise --source Hello.pas --emit-ir
----
== What Is Dropped From Classic Pascal
[cols="1,3", options="header"]
|===
| Feature | Reason for removal
| `ShortString`, `AnsiString`, `WideString`, `UnicodeString`
| Replaced by a single UTF-8 reference-counted `string` type
| `with` statement
| Source of hard-to-diagnose symbol resolution bugs; breaks static analysis
| Old-style `object` types
| Use `record` (stack/value) or `class` (heap/reference) instead
| COM-style interface GUIDs
| Interface dispatch via compile-time vtable; GUIDs are unnecessary complexity
| Multiple language modes
| One dialect, maintained well, beats five dialects maintained poorly
| `assign`, `reset`, `rewrite`, `blockread`
| Replaced by a stream-based I/O RTL
| `TObject` vs `TInterfacedObject` split
| One unified class model under automatic reference counting; `[Weak]`
breaks cycles
|===
== Licence
BSD 3-Clause. See link:LICENCE[LICENCE].