Skip to content
tinyBigGAMESPublic

About

PaskalCPP is a systems language by Jarrod Davis: Pascal/Oberon-style syntax that transpiles to C++23 and builds with a bundled Zig/Clang toolchain. Mix PaskalCPP and C++ in one file, no bindings. Includes a Delphi-built compiler and language server, an Electron/Monaco editor, and diagnostics mapped to your source. Native Windows and Linux binaries.

Topics

Resources

Code of conduct

Contributing

Stars

9 stars

Watchers

2 watching

Forks

Repository files navigation

PaskalCPP

Discord Follow on Bluesky Facebook Group

Write Pascal-style code, use any C and C++ library.

Homepage · Documentation · Releases ·

PaskalCPP

PaskalCPP is a minimal, Pascal and Oberon inspired systems programming language that compiles to C++23 and mixes freely with C++ in the same source file, so every C and C++ library is available with no bindings.

🔥 What it is

PaskalCPP's syntax follows Pascal and Oberon: blocks open and close with words, assignment is := and equality is =, every control-flow construct carries its own end, every statement ends with ;, and names are declared before they are used.

The compiler writes a C++23 header and source for each module and builds them with the bundled Zig toolchain (clang) through zig build, which caches compiles. One source builds an executable (module exe), a shared library (module dll) or a static library (module lib), for x86_64-windows-gnu and x86_64-linux-gnu, from Windows.

C and C++ are part of the language. A library is used by #include-ing its header in the .pcpp file and calling it: there is no import, binding or wrapper layer. Its names are opaque to PaskalCPP and checked by clang.

🚀 A first look

Here is cpp_mixing_std.pcpp (below):

cpp_mixing_std.pcpp: the C++ standard library used straight from PaskalCPP: a std::string and a std::vector as variables, their methods, std::sort, std::pow, and a C++ template written in the module and called from the PaskalCPP body. No binding anywhere: the headers are included.

module exe cpp_mixing_std;

#include <string>
#include <vector>
#include <cmath>
#include <algorithm>

template<typename T>
T Max2(T a, T b) {
  return a > b ? a : b;
}

var
  LS: std::string;
  LV: std::vector<int>;
  LD: float64;
  LX: int32;

begin
  LS := "hello world";
  if LS.find("world") <> std::string::npos then
    println("found at {}", LS.find("world"));
  end;

  LV.push_back(3);
  LV.push_back(1);
  LV.push_back(2);
  std::sort(LV.begin(), LV.end());
  println("sorted {} {} {}", LV[0], LV[1], LV[2]);
  println("size {}", LV.size());

  LX := 3;
  LD := std::pow(float64(LX), 2.0);
  LX := Max2(LX, int32(LD));
  println("max {}", LX);
end.

Output on x86_64-windows-gnu and x86_64-linux-gnu:

found at 6
sorted 1 2 3
size 3
max 9
[Heap] Allocs: 0, Frees: 0, Leaked: 0

Build it and run it with one command:

pcpp cpp_mixing_std.pcpp -r

With no @optimize a build is debug, and a debug build prints the runtime's heap report (the [Heap] line) when the program ends.

✨ Highlights

  • Readable by design. Pascal and Oberon blocks, := for assignment, ; after every statement, each construct closed by its own end.
  • C++ is the surface. #include a header and call it. A C++ type (std::string, std::vector<int>) can be the type of a PaskalCPP variable, and C++ declarations (a struct, a function, a template) stand at module level.
  • Errors speak PaskalCPP. A mistake on a PaskalCPP construct is reported in PaskalCPP's words and types. What only C++ can judge is clang's or the linker's own message, mapped back to the .pcpp file, line and column.
  • The toolchain is in the box. Zig and clang ship in the res folder beside pcpp.exe: one pcpp command turns a source file into a native binary.
  • Two targets, one source. @target or pcpp -t picks x86_64-windows-gnu or x86_64-linux-gnu; pcpp <file> -r runs a Linux build through WSL.

🛠️ Tools

  • pcpp, the compiler: pcpp <source> [OPTIONS]; pcpp -h lists every option.
  • The PaskalCPP Editor (pcpp editor [files]): an Electron application whose editing surface is Monaco, with build, run and debug.
  • A language server (pcpp --lsp): the Language Server Protocol server the editor runs, and any LSP client can.
  • A debugger for the x86_64-windows-gnu target: the console debugger (pcpp <file> -d) and the debug adapter (pcpp --dap) the editor runs, both on one engine.

📦 Getting PaskalCPP

Download the latest release from GitHub Releases. The documentation is online at paskalcpp.org/docs and ships in the release as docs/html/index.html; start with the tour.

🔧 Building from source

For contributors who want to change the compiler itself.

Requirement
Host OS Windows x64
Compiler Delphi (RAD Studio)
A release The latest release: the repo holds the sources only, and the Zig toolchain, the vendor libraries and every other binary come in the release
  1. Download ZIP or clone the repo:

    git clone https://github.com/tinyBigGAMES/PaskalCPP.git
    
  2. Download the latest release and unzip it into the repo folder, so the toolchain, the libraries and the binaries are in place. A build from source needs them too.

  3. Run bin\build-pcpp.cmd (it loads RAD Studio's rsvars.bat from Studio\37.0: edit that line for another install), or open projects\PaskalCPP.groupproj in the Delphi IDE and build the pcpp and testbed projects. This produces pcpp.exe and the test runner testbed.exe in bin\. bin\testbed.exe -all runs the test suite and exits 0 when it passes; bin\testbed.exe -h lists the rest.

❓ FAQ

Every build fails with ZB0016: "unable to find zig installation directory"

The bundled Zig toolchain is incomplete. zig needs its lib folder beside zig.exe, and when bin\res\zig\lib\std\std.zig is missing every build fails with this message, which is zig's own.

To fix it:

  1. Delete the bin\res\zig folder.
  2. Extract the release zip again with 7-Zip or WinRAR.
  3. Check that bin\res\zig\lib\std\std.zig exists.
The first build is slow

The first build for a target also compiles the libraries every program links (the C runtime, libc++, libc++abi, libunwind, compiler_rt and the system import libraries) and keeps them in zig's cache, bin\res\zig\.zig-cache. That build can take a few minutes.

Later builds for that target reuse them, at another optimize level too, and take seconds. The first build for the other target (x86_64-linux-gnu) compiles its own libraries once in the same way. Deleting bin\res\zig\.zig-cache makes the next build of each target slow again. How a build works is in Building.

A Linux window opens small under WSL2, and the program reads a display scale of 1

A Linux build run on Windows (-t x86_64-linux-gnu -r) runs under WSL2, and its window is shown by WSLg, whose compositor (Weston) gives every Linux program a display scale of 1 by default. A program that sizes its window by that scale (the SDL3 examples call SDL_GetWindowDisplayScale) opens at 1x on a 150% monitor, smaller than the same program built for Windows.

To make WSLg follow each monitor's Windows scale, create the file .wslgconfig in your Windows user folder (C:\Users\<you>\.wslgconfig for WSL from the Microsoft Store; C:\ProgramData\Microsoft\WSL\.wslgconfig for the WSL built into Windows) holding:

[system-distro-env]
WESTON_RDP_HI_DPI_SCALING=true
WESTON_RDP_FRACTIONAL_HI_DPI_SCALING=true

then run wsl --shutdown (WSLg reads the file when it starts). The Linux window then opens at the size Windows scales it to on that monitor. The program itself still reads a scale of 1: Windows enlarges the window, the program does not draw at the higher resolution.

Leave out WESTON_RDP_DEBUG_DESKTOP_SCALING_FACTOR: it forces one factor on every monitor instead of each monitor's own.

More answers are in the FAQ.

🤝 Contributing

  • Report bugs with a minimal .pcpp reproduction, the exact command used, and the compiler's diagnostics.
  • Suggest features: describe the use case first, then the behavior you have in mind.
  • Submit pull requests for bug fixes, documentation, new test cases and well-scoped features; open an issue first for substantial language or compiler changes.
  • Review and discuss open pull requests and issues.

Read CONTRIBUTING.md and the Code of Conduct before you start. Bugs can also go through the report page. Join the Discord to talk development, ask questions, or show what you are building. Contact: support [at] paskalcpp [dot] org.

💖 Support the project

If PaskalCPP saves you time, helps you learn, or sparks something useful:

  • ⭐ Star the repo: it costs nothing and helps others find the project
  • 📣 Spread the word: write a post, mention it in a community, or share a screenshot
  • 💬 Join the community: show what you are building and help shape what comes next on Discord or in the Facebook group
  • 🧪 Build something real: real usage finds issues that synthetic tests miss
  • 💖 Become a sponsor: sponsorship directly funds development, examples, and documentation

📜 License

PaskalCPP is free and open source under the Mozilla Public License 2.0: see LICENSE and NOTICE.md. The runtime and standard library files that PaskalCPP builds into your programs carry an additional permission: see RUNTIME-EXCEPTION.md. The PaskalCPP name and marks: TRADEMARK.md.

🔗 Links

PaskalCPP™ Programming Language

Copyright © 2026-present tinyBigGAMES™ LLC
All Rights Reserved.

About

PaskalCPP is a systems language by Jarrod Davis: Pascal/Oberon-style syntax that transpiles to C++23 and builds with a bundled Zig/Clang toolchain. Mix PaskalCPP and C++ in one file, no bindings. Includes a Delphi-built compiler and language server, an Electron/Monaco editor, and diagnostics mapped to your source. Native Windows and Linux binaries.

Topics

Resources

Code of conduct

Contributing

Stars

9 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Contributors

Languages