188 lines
5.2 KiB
Plaintext
188 lines
5.2 KiB
Plaintext
|
|
= Clean Pascal Compiler
|
||
|
|
: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.
|
||
|
|
* *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
|
||
|
|
| In progress
|
||
|
|
|
||
|
|
| 2
|
||
|
|
| Type system — classes, records, ARC, exceptions
|
||
|
|
| Planned
|
||
|
|
|
||
|
|
| 3
|
||
|
|
| Generics + zero-GUID interfaces
|
||
|
|
| Planned
|
||
|
|
|
||
|
|
| 4
|
||
|
|
| OPDF debug info emission
|
||
|
|
| Planned
|
||
|
|
|
||
|
|
| 5
|
||
|
|
| Self-hosting + LLVM + Windows
|
||
|
|
| 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 clean-pascal-compiler
|
||
|
|
----
|
||
|
|
|
||
|
|
=== Running the compiler
|
||
|
|
|
||
|
|
Once built, the compiler binary is at `compiler/target/cleanpascal`.
|
||
|
|
|
||
|
|
[source,shell]
|
||
|
|
----
|
||
|
|
# Compile a single file
|
||
|
|
compiler/target/cleanpascal --source Hello.pas --output Hello
|
||
|
|
|
||
|
|
# Compile via project.xml
|
||
|
|
compiler/target/cleanpascal --project project.xml --config debug --output myapp
|
||
|
|
|
||
|
|
# Emit QBE IR (useful for debugging the compiler itself)
|
||
|
|
compiler/target/cleanpascal --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
|
||
|
|
|===
|
||
|
|
|
||
|
|
== Licence
|
||
|
|
|
||
|
|
BSD 3-Clause. See link:LICENCE[LICENCE].
|