JetPascal is a Pascal transpiler that generates clean, readable C++ code and compiles it using the Zig build system (Clang backend). It's designed for developers who love Pascal's clean syntax but need C++'s performance, ecosystem access, and cross-platform capabilities.
🚀 Key Innovation: JetPascal breaks down the traditional barrier between Pascal and C/C++. With the (*EMIT*) directive, you can seamlessly integrate C++ code directly into your Pascal programs, giving you access to the vast ecosystem of C/C++ libraries while maintaining Pascal's readability and structure.
📦 Everything Included: No external dependencies to download - everything you need is in the box!
- ✨ Pascal's Clarity: Clean, readable syntax that's easy to learn and maintain
- 💪 C++'s Power: Direct access to C++ standard library, modern C++ features, and optimizations
- 🌍 C/C++ Ecosystem: Tap into decades of C/C++ libraries - graphics, networking, AI, you name it
- ⚡ Native Performance: Compiles to optimized machine code via Clang
- 🔧 True Cross-Platform: Windows, Linux, macOS (Intel & ARM), all from a single codebase
Traditional Pascal has been isolated from the C/C++ ecosystem. JetPascal changes that:
- 📦 Static Linking: Link C/C++ libraries statically (like raylib) - something difficult to achieve in traditional Delphi
- 🔗 Direct C++ Integration: Use
(*EMIT*)to write inline C++ when you need it - 📚 Standard Library Access: Full access to C++ STL algorithms, containers, and utilities
- 🎮 Modern APIs: Call any C/C++ API directly from Pascal code
- ⚡ Zero Overhead: Generated C++ code means zero foreign function interface cost
- ✅ Basic Types: Integer, Int64, UInt64, Cardinal, Word, Byte, Boolean, Char, Single, Double, String
- ✅ Control Flow: if-then-else, for-to/downto, while-do, repeat-until, case-of
- ✅ Structured Types: Records, static arrays, dynamic arrays, multi-dimensional arrays, enumerations
- ✅ Pointers: Full pointer support with ^, @, New, Dispose operations
- ✅ Functions & Procedures: Nested routines, forward declarations, parameter passing (const, var, out)
- ✅ Exception Handling: try-except-finally blocks with RaiseException
- ✅ Units: Modular programming with interface/implementation sections
- ✅ Type Aliases: Custom type definitions
- ✅ Typed Constants: Compile-time constant initialization
- ✅ Sets: Include/Exclude operations
- ✅ With Statement: Simplified record field access
- ✅ String Operations: Copy, Length, SetLength, string concatenation
- ✅ File I/O: Text files, binary files, typed files
- ✅ Compiler Directives: Complete build control via directives
Built-in functions for common operations:
- Memory: New, Dispose, GetMem, FreeMem, ReallocMem, AllocMem, FillChar, FillByte, Move
- Arrays/Strings: SetLength, Length, High, Low, Copy, Insert, Delete
- I/O: WriteLn, Write, ReadLn, Read
- Ordinal: Ord, Chr, Succ, Pred, Odd, Inc, Dec
- Command Line: ParamCount, ParamStr
- Utilities: SizeOf, Assigned, Halt
- System: Format, Val, Str, Swap
JetPascal comes with a standard library (res\libs\std):
- SysUtils: String utilities, conversions, file operations
- StrUtils: Advanced string manipulation
- Math: Mathematical functions
- DateUtils: Date and time utilities
- FileUtils: File system operations
- Types: Common type definitions
raylib Integration - A complete game development library is included (res\libs\raylib):
- 2D/3D graphics
- Audio
- Input handling
- Collision detection
- Statically linkable (unlike traditional Delphi)
The raylib Pascal bindings let you create games and graphics applications with ease, and JetPascal can link it statically for single-file executables.
Download the latest release from GitHub Releases.
Each release includes:
Jet.exe- The JetPascal compilerresfolder - Standard libraries, Zig toolchain, raylib, and everything you need
That's it! No external dependencies to install. Everything is self-contained.
Create hello.pas:
program Hello;
begin
WriteLn('Hello from JetPascal!');
end.JetPascal uses a project-based workflow:
jet init MyProjectThis creates a new folder with:
src\- Your Pascal source filesbuild.zig- Zig build configuration (auto-generated)- Template source file to get started
Optional: Specify project type:
jet init MyGame --template program # Executable (default)
jet init MyLib --template library # Shared library (.dll/.so)
jet init MyUnit --template unit # Static library (.lib/.a)cd MyProject
jet buildThis will:
- Transpile Pascal to C++
- Compile C++ via Zig/Clang
- Link the executable
- Output to
zig-out\bin\folder
jet runjet cleanNeed to use Zig directly?
jet zig version
jet zig cc -c myfile.cjet help
jet --version🔥 Innovation: JetPascal gives you complete control over every aspect of the build process through compiler directives in your Pascal source code. No external build files needed - everything is specified in your Pascal code!
JetPascal supports the following compiler directives:
{$OPTIMIZATION mode} - Set optimization level
{$OPTIMIZATION Debug} // Debug build with symbols
{$OPTIMIZATION ReleaseSafe} // Optimized with safety checks
{$OPTIMIZATION ReleaseFast} // Maximum speed optimization
{$OPTIMIZATION ReleaseSmall} // Optimize for size{$TARGET target} - Set compilation target
{$TARGET native} // Native platform (default)
{$TARGET x86_64-windows} // Windows x64
{$TARGET x86_64-linux} // Linux x64
{$TARGET aarch64-macos} // macOS ARM (Apple Silicon)
{$TARGET aarch64-linux} // Linux ARM
{$TARGET wasm32-wasi} // WebAssembly{$APPTYPE type} - Set application type (Windows)
{$APPTYPE CONSOLE} // Console application (default)
{$APPTYPE GUI} // GUI application (no console window){$UNIT_PATH path} - Add Pascal unit search path
{$UNIT_PATH '.\libs\myunits'}
{$UNIT_PATH 'C:\Libraries\Pascal'}{$INCLUDE_PATH path} - Add C++ include path
{$INCLUDE_PATH '.\cpp\includes'}
{$INCLUDE_PATH 'C:\Libraries\CPP\include'}{$LIBRARY_PATH path} - Add library search path
{$LIBRARY_PATH '.\libs'}
{$LIBRARY_PATH 'C:\Libraries\raylib'}{$LINK library} - Link against a library
{$LINK raylib.lib} // Static library
{$LINK opengl32} // System library
{$LINK ws2_32} // Windows sockets{$INCLUDE_HEADER header} - Include C++ header in generated code
{$INCLUDE_HEADER '<cmath>'} // System header
{$INCLUDE_HEADER '<algorithm>'} // STL header
{$INCLUDE_HEADER '"myheader.h"'} // Local header
{$INCLUDE_HEADER '<raylib.h>'} // Third-party header{$ABI mode} - Set application binary interface (ABI) for external functions for a library
{$ABI C} // C ABI
{$ABI CPP} // C++ ABI (default)Here's a real-world example showing the power of compiler directives:
program MyGame;
// Build configuration
{$OPTIMIZATION ReleaseFast}
{$TARGET native}
{$APPTYPE GUI}
// Library paths
{$LIBRARY_PATH '.\res\libs\raylib\lib'}
{$UNIT_PATH '.\res\libs\std'}
// Link raylib statically
{$LINK raylib.lib}
{$LINK opengl32}
{$LINK gdi32}
{$LINK winmm}
// Include C++ headers
{$INCLUDE_HEADER '<raylib.h>'}
{$INCLUDE_HEADER '<cmath>'}
uses
SysUtils,
raylib;
begin
InitWindow(800, 600, 'My JetPascal Game');
while not WindowShouldClose() do
begin
// Game loop
end;
CloseWindow();
end.That's it! Everything is configured in the Pascal source. No external build configuration files needed. When you run jet build, JetPascal reads these directives and generates the appropriate build.zig file automatically.
Traditional compilers require:
- Separate build files (Makefiles, CMake, MSBuild, etc.)
- External configuration (project files, config files)
- Build system knowledge (learning CMake, make, etc.)
JetPascal's approach:
- ✅ Everything in source code - Directives in your Pascal files
- ✅ Self-documenting - Build configuration visible right in the code
- ✅ No external files - Just Pascal source + compiler
- ✅ Complete control - Every aspect of compilation/linking configurable
- ✅ Cross-platform made easy - Just change
{$TARGET}directive
Cross-compile to macOS from Windows?
{$TARGET aarch64-macos}Build for WebAssembly?
{$TARGET wasm32-wasi}That's all it takes! No separate build configurations, no platform-specific makefiles.
- Directives are case-insensitive:
{$LINK}={$link}={$Link} - Paths can use quotes (single or double):
{$UNIT_PATH 'path'}or{$UNIT_PATH "path"} - Angle brackets for system headers:
{$INCLUDE_HEADER '<cmath>'} - Multiple directives allowed - they accumulate
- Main source file directives take priority for build settings
- Only the main file's
{$OPTIMIZATION},{$TARGET}, and{$APPTYPE}are used
program ProgramSimple;
begin
WriteLn('Simple Program');
end.program ProgramControlFlow;
var
GValue: Integer;
GCounter: Integer;
GSum: Integer;
begin
WriteLn('=== Control Flow Demo ===');
GValue := 10;
WriteLn('Initial value: ', GValue);
if GValue > 0 then
GValue := GValue + 1
else
GValue := 0;
WriteLn('After if-then-else: ', GValue);
GCounter := 0;
while GCounter < 5 do
begin
GCounter := GCounter + 1;
end;
WriteLn('After while loop: ', GCounter);
GSum := 0;
for GCounter := 1 to 10 do
begin
GSum := GSum + GCounter;
end;
WriteLn('Sum 1 to 10: ', GSum);
end.program ProgramArrays;
type
TIntArray = array[0..4] of Integer;
TMatrix = array[0..1, 0..2] of Integer;
var
GArray: TIntArray;
GMatrix: TMatrix;
GDynamic: array of Integer;
GIndex: Integer;
begin
// Static array
GArray[0] := 10;
GArray[1] := 20;
GArray[2] := 30;
WriteLn('GArray[0]: ', GArray[0]);
// Multi-dimensional array
GMatrix[0, 0] := 1;
GMatrix[0, 1] := 2;
WriteLn('GMatrix[0,0]: ', GMatrix[0, 0]);
// Dynamic array
SetLength(GDynamic, 5);
GDynamic[0] := 100;
WriteLn('Dynamic length: ', Length(GDynamic));
// Array in loop
for GIndex := 0 to 4 do
begin
GArray[GIndex] := GIndex * 10;
WriteLn('GArray[', GIndex, ']: ', GArray[GIndex]);
end;
end.program ProgramComplete;
type
TNode = record
Data: Integer;
Next: PNode;
end;
PNode = ^TNode;
function CreateNode(const AValue: Integer): PNode;
var
LNode: PNode;
begin
New(LNode);
LNode^.Data := AValue;
LNode^.Next := nil;
Result := LNode;
end;
procedure AddNode(var AHead: PNode; const AValue: Integer);
var
LNewNode: PNode;
begin
LNewNode := CreateNode(AValue);
LNewNode^.Next := AHead;
AHead := LNewNode;
end;
function CountNodes(const AHead: PNode): Integer;
var
LCurrent: PNode;
LCount: Integer;
begin
LCount := 0;
LCurrent := AHead;
while LCurrent <> nil do
begin
LCount := LCount + 1;
LCurrent := LCurrent^.Next;
end;
Result := LCount;
end;
var
GHead: PNode;
GCount: Integer;
GIndex: Integer;
begin
GHead := nil;
for GIndex := 1 to 5 do
begin
AddNode(GHead, GIndex * 10);
WriteLn('Added node: ', GIndex * 10);
end;
GCount := CountNodes(GHead);
WriteLn('Total nodes: ', GCount);
end.program ProgramExceptions;
procedure RiskyOperation;
begin
WriteLn('About to raise exception...');
RaiseException('Something went wrong!');
WriteLn('This will not print');
end;
var
LMessage: String;
begin
WriteLn('=== Exception Handling ===');
try
WriteLn('Before exception');
RiskyOperation();
WriteLn('After exception (not reached)');
except
LMessage := GetExceptionMessage();
WriteLn('Caught exception: "', LMessage, '"');
end;
WriteLn('Program continues normally');
try
WriteLn('In try block');
finally
WriteLn('Finally block always executes');
end;
end.program ProgramStringFunctions;
uses
SysUtils,
StrUtils;
var
LS: String;
LS2: String;
LBool: Boolean;
LI: Integer;
begin
WriteLn('=== String Functions ===');
// StringReplace
LS := 'Hello World';
LS2 := StringReplace(LS, 'World', 'JetPascal');
WriteLn('Replace: "', LS2, '"');
// CompareStr (case-sensitive)
LI := CompareStr('Hello', 'Hello');
WriteLn('CompareStr("Hello", "Hello") = ', LI);
// SameText (case-insensitive)
LBool := SameText('Hello', 'hello');
if LBool then
WriteLn('SameText: true (case-insensitive)');
// QuotedStr
LS := QuotedStr('Hello World');
WriteLn('QuotedStr: ', LS);
end.JetPascal's (*EMIT*) directive is a game-changer. It allows you to write inline C++ code directly in your Pascal programs, giving you seamless access to the entire C/C++ ecosystem.
Think of it like inline assembly in traditional Pascal/Delphi, but instead of dropping to machine code, you're dropping to C++ - which means you get:
- 📚 C++ Standard Library: STL algorithms, containers, file systems, threading, and more
- 🌐 Third-Party C++ Libraries: OpenCV, Boost, Qt, SFML, SDL - the entire C++ universe
- 💻 Platform APIs: Direct access to Windows API, POSIX, macOS frameworks
- ⚡ Performance: Hand-optimized C++ code when Pascal isn't enough
- 🚀 Modern Features: Lambdas, templates, smart pointers, ranges
{$INCLUDE_HEADER '<cmath>'}
function Sqrt(const AValue: Double): Double;
begin
(*EMIT return std::sqrt(AValue); *)
end;The (*EMIT*) block contains raw C++ code that's emitted directly into the generated output. With #line directive support, errors point back to your Pascal source - you never need to look at the generated C++.
{$INCLUDE_HEADER '<algorithm>'}
function ReverseString(const AText: string): string;
begin
(*EMIT
std::string result = AText;
std::reverse(result.begin(), result.end());
return result;
*)
end;{$INCLUDE_HEADER '<filesystem>'}
function FileExists(const AFileName: string): Boolean;
begin
(*EMIT
std::filesystem::path p(AFileName);
return std::filesystem::exists(p) && std::filesystem::is_regular_file(p);
*)
end;{$INCLUDE_HEADER '<cmath>'}
{$INCLUDE_HEADER '<algorithm>'}
function Distance(const X1, Y1, X2, Y2: Double): Double;
begin
(*EMIT
double dx = X2 - X1;
double dy = Y2 - Y1;
return std::sqrt(dx * dx + dy * dy);
*)
end;
function Clamp(const AValue, AMin, AMax: Double): Double;
begin
(*EMIT return std::clamp(AValue, AMin, AMax); *)
end;{$INCLUDE_HEADER '<raylib.h>'}
procedure Raylib_InitWindow(const AWidth, AHeight: Integer; const ATitle: string);
begin
(*EMIT InitWindow(AWidth, AHeight, ATitle.c_str()); *)
end;
function RayLib_IsKeyPressed(const AKey: Integer): Boolean;
begin
(*EMIT return IsKeyPressed(AKey); *)
end;Traditional Pascal has been an island - isolated from the rich C/C++ ecosystem. JetPascal changes that:
- 🚫 No More Wrappers: Don't write complex FFI wrappers - just use
(*EMIT*)and call the C++ API directly - 📦 Static Linking: Link C/C++ libraries statically for single-file deployment (difficult in traditional Delphi)
- ⚡ Zero Overhead: It's not FFI - it's native C++ code generation
- 📈 Gradual Optimization: Write in Pascal, profile, optimize hotspots with C++
- 🎓 Learn One, Use All: Learn Pascal syntax, get access to 40+ years of C/C++ libraries
Use (*EMIT*) when you need:
- ✅ Access to C++ standard library features
- ✅ Integration with existing C/C++ libraries
- ✅ Performance-critical code sections
- ✅ Platform-specific APIs
- ✅ Features not yet implemented in Pascal
Best Practices:
- 📝 Use
{$INCLUDE_HEADER}for required C++ headers - 💬 Document what the C++ code does
- 🏗️ Use Pascal for high-level structure, C++ for low-level details
- 🎯 Keep it simple - prefer single-line emissions
Imagine you want to use a C++ JSON library:
{$INCLUDE_HEADER '<nlohmann/json.hpp>'}
function ParseJSON(const AJsonText: string): Boolean;
begin
(*EMIT
try {
auto json = nlohmann::json::parse(AJsonText);
return true;
} catch (...) {
return false;
}
*)
end;
function GetJSONValue(const AJsonText, AKey: string): string;
begin
(*EMIT
try {
auto json = nlohmann::json::parse(AJsonText);
return json[AKey].get<std::string>();
} catch (...) {
return "";
}
*)
end;No wrapper needed. No FFI. Just direct integration. 🚀
- 🔧 RAD Studio / Delphi 12.3 (tested on Windows 11)
- 📦 JetPascal Release - Download from releases to get the
resfolder with binaries
Important: Everything is self-contained - no external dependencies to download! However, the res folder containing the Zig toolchain and other binaries is only included in releases.
-
📥 Clone the repository:
git clone https://github.com/tinyBigGAMES/JetPascal.git cd JetPascal -
📦 Get the
resfolder:- Download the latest release from GitHub
- Extract the
resfolder from the release - Copy it to
JetPascal\bin\res
This folder contains:
- Zig toolchain
- Standard Pascal libraries
- raylib binaries
- Test files
You need this to compile and link!
-
🔨 Open in Delphi:
- Navigate to
srcfolder - Open:
JetPascal - Accelerate Your Code!.groupproj - This loads all projects in the IDE
- Navigate to
-
⚙️ Compile each project:
- Jet.dproj - Command-line interface (produces
Jet.exe) - JPTester.dproj - Test runner (produces
JPTester.exe) - JPBench_Delphi.dproj - Performance benchmarks (Delphi)
- Jet.dproj - Command-line interface (produces
-
✅ Run tests:
JPTester.exe
- Tested with Delphi 12.3 on Windows 11
- Everything you need is included - no external dependencies
- The
resfolder in releases contains all the binary tools - Output goes to
binfolder
JetPascal/
├── 📁 bin/ # Executables and output
│ ├── Jet.exe # JetPascal compiler
│ ├── JPTester.exe # Test runner
│ └── 📁 res/ # Runtime resources (from release)
│ ├── 📁 libs/ # Standard libraries
│ │ ├── 📁 std/ # Pascal standard library
│ │ └── 📁 raylib/ # raylib game library
│ ├── 📁 runtime/ # C++ runtime files
│ └── 📁 tests/ # Test suite with real examples
├── 📁 src/ # Source code
│ ├── 📁 compiler/ # Compiler implementation
│ ├── 📁 cli/ # Command-line interface
│ ├── 📁 tester/ # Test runner
│ └── JetPascal - *.groupproj # Delphi group project
├── 📁 docs/ # Documentation
└── LICENSE # BSD 3-Clause License
JetPascal uses a polymorphic wrapper architecture:
- 📖 Parser: Uses DelphiAST to parse Pascal source code into an AST
- 🔄 Preprocessor: Processes directives like
(*EMIT*)and{$INCLUDE_HEADER} - 🎯 Transpiler: Walks the AST, creating wrapper objects for each construct (~200 lines)
- 🧩 Wrappers: Self-contained classes that generate C++ code for their construct
- 📝 Code Generator: Emits clean, readable C++ code
- ⚙️ Zig Compiler: Compiles C++ to native code using Clang backend
- 🔄 Natural control flow: break/continue/return work seamlessly
- 📝 String handling: std::string provides robust string support
- 🛡️ Exception handling: C++ exceptions map well to Pascal try-except
- ⚡ Optimization: Clang's world-class optimizer
- 🌍 Cross-platform: Zig handles all the platform complexity
- 🔧 Universal toolchain: One tool for all platforms
- 🌐 Cross-compilation: Built-in, no setup needed
- 🚀 Latest Clang: Modern C++ features and optimizations
- ✨ Zero hassle: No MSVC/MinGW/GCC configuration headaches
JetPascal follows these principles:
- 📝 Pascal First: Clean Pascal syntax is the primary interface
- 💪 C++ When Needed: Drop to C++ with
(*EMIT*)for power features - ⚡ Performance: Generate efficient C++ that compiles to fast native code
- 🔄 Compatibility: Stay close to standard Pascal/Object Pascal semantics
- ✨ Simplicity: Avoid unnecessary complexity in the language design
- 🔧 Extensibility: Easy to add new features via wrapper architecture
- 🎯 Total Control: Compiler directives give complete build control
JetPascal is open source (BSD 3-Clause License). Contributions are welcome!
Areas where help is appreciated:
- 📚 Additional standard library functions
- 🧪 More test cases
- 📖 Documentation improvements
- 🐛 Bug reports and fixes
- 🖥️ Platform-specific testing
JetPascal is released under the BSD 3-Clause License.
Copyright (c) 2025-present, tinyBigGAMES LLC
All rights reserved.
See the LICENSE file for full details.
- 🌐 Website: https://jetpascal.org
- 💻 GitHub: https://github.com/tinyBigGAMES/JetPascal
- 🐛 Issues: https://github.com/tinyBigGAMES/JetPascal/issues
⚡ JetPascal™ - Accelerate Your Code! ⚡
Copyright © 2025-present tinyBigGAMES™ LLC. All Rights Reserved.
