This repository contains a native compiler for the 1981 IBM Pascal dialect. It targets LLVM IR, the System V AMD64 ABI, and NVIDIA NVPTX.
Install these packages before you build the toolchain (for example, on Debian or Ubuntu Linux x86_64):
clang(C compiler and linker)make(build tool)libllvm-20-dev/llvm-20(LLVM 20 library and headers)libcjson-dev(cJSON library and headers)indent(C code formatting tool)python3andpip3with the reference compiler package:pip3 install 'https://github.com/jamesmcclain/pascal-1981/archive/99a8f3f4b4f5259a43301c9b8879f3fc891d3503.zip'
src/: Native compiler stages and driver in Pascal (lexer.pas,parser.pas,typechecker.pas,codegen.pas,driver.pas,jsonutil.pas,jsonutil.inc).runtime/: C runtime static library and headers (libpascalrt.a,pascalrt.h).bin/: Compiler driver (pascal1981-native, aliaspascal1981) and stage binaries (lexer,parser,typechecker,codegen).scripts/: Build scripts (build-stage.sh), formatting scripts (beautify.sh), and git hooks (rungit config core.hooksPath scripts/hooksonce per clone to enable the pre-commit formatting hook — it's local config, so a fresh checkout won't run it until you do). The multi-generation bootstrap itself is driven by the rootMakefile'sbootstraptarget, not a standalone script.tests/: Test suites (golden files, unit tests, integration tests, dialect fixtures).
To build the runtime, driver, and bootstrap all compiler stages:
makeBy default, the build uses llvm-config (or llvm-config-20 if llvm-config is not in PATH) to dynamically determine LLVM linker flags and libraries. You can explicitly override this by setting LLVM_CONFIG:
LLVM_CONFIG=llvm-config-20 makeYou can also override the C compiler/linker (default clang) with CC:
CC=clang-20 makeTo rebuild only the four compiler stages, run:
make bootstrapThen build the installed Pascal driver from the fixed-point stages:
make driverThe bootstrap process is composed of four steps:
- Generation 1 (Hybrid): Builds the native compiler stages with the Python reference compiler (
pascal1981). - Generation 2 (Self-hosted): Recompiles all native compiler stages with the Generation 1 binaries.
- Generation 3 (Self-hosted): Recompiles all native compiler stages with the Generation 2 binaries.
- Generation 4 (Fixed Point): Recompiles all native compiler stages with the Generation 3 binaries and verifies binary identity (
cmp).make driverthen compilessrc/driver.paswith those stages and installs it asbin/pascal1981-native(withbin/pascal1981as its alias).
To compile a Pascal program with the native compiler, run:
bin/pascal1981-native hello.pas -o hello
./helloSupported options:
-o <file>: Set output path-c: Compile to object file (.o)-S: Emit LLVM IR (.ll)-O0,-O1,-O2,-O3: Set optimization level--emit-ptx: Emit NVPTX assembly for device kernels-v: Print pipeline commands
Run the routine test suites:
make testThis target runs the driver, native, checklit, and pre-commit-hook tests. The test runners do not require pytest.
This target does not run the reference-parity, bootstrap, or Emacs tests.
Use these targets for a specific test group:
| Target | Test group |
|---|---|
make test-driver |
Driver command-line behavior |
make test-native |
Routine native compiler tests |
make test-gpu |
CUDA compilation and execution on an NVIDIA GPU |
make test-reference-parity |
Native compiler parity with the Python reference compiler |
make test-elisp |
Emacs major-mode ERT tests |
make test-bootstrap |
Clean bootstrap and fixed-point comparison |
The test-gpu target skips the test if a CUDA prerequisite is not available.
The test-reference-parity target requires Python and pytest. The test-elisp target requires Emacs and builds the compiler stages first.
See tests/README.md for more information about the compiler test suites.