Skip to content

JetPascal - Accelerate Your Code! 🚀 A next-generation Pascal-to-C++ transpiler that turns your Delphi/Pascal code into blazing-fast native executables. Built with a clean polymorphic architecture that emits modern C++ code, then compiles it using the Zig toolchain for cross-platform deployment.

License

Notifications You must be signed in to change notification settings

tinyBigGAMES/JetPascal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JetPascal Join Facebook Group Chat on Discord Follow on Bluesky

🎯 What is JetPascal?

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!

🌟 Why JetPascal?

The Best of Both Worlds

  • ✨ 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

🔓 Breaking Down the Walls

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

✨ Key Features

Language Features

  • 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

🔧 Intrinsic Functions

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

📚 Standard Library

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

🎮 Third-Party Libraries

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.

🚀 Quick Start

📥 Download

Download the latest release from GitHub Releases.

Each release includes:

  • Jet.exe - The JetPascal compiler
  • res folder - Standard libraries, Zig toolchain, raylib, and everything you need

That's it! No external dependencies to install. Everything is self-contained.

👨‍💻 Your First Program

Create hello.pas:

program Hello;

begin
  WriteLn('Hello from JetPascal!');
end.

🎯 Using the CLI

JetPascal uses a project-based workflow:

Create a New Project

jet init MyProject

This creates a new folder with:

  • src\ - Your Pascal source files
  • build.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)

Build Your Project

cd MyProject
jet build

This will:

  1. Transpile Pascal to C++
  2. Compile C++ via Zig/Clang
  3. Link the executable
  4. Output to zig-out\bin\ folder

Run Your Program

jet run

Clean Build Artifacts

jet clean

Direct Zig Access

Need to use Zig directly?

jet zig version
jet zig cc -c myfile.c

Get Help

jet help
jet --version

🎛️ Compiler Directives - Total Build Control

🔥 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!

Available Directives

JetPascal supports the following compiler directives:

🎯 Build Configuration

{$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)

📁 Path Configuration

{$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'}

🔗 Linking

{$LINK library} - Link against a library

{$LINK raylib.lib}           // Static library
{$LINK opengl32}             // System library
{$LINK ws2_32}               // Windows sockets

📦 C++ Integration

{$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)

💡 Complete Example

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.

🎯 Why This Is Innovative

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.

📋 Directive Rules

  • 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

📖 Code Examples

Simple Program

program ProgramSimple;

begin
  WriteLn('Simple Program');
end.

🎮 Control Flow

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.

📊 Arrays and Records

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.

🔗 Pointers and Linked List

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.

🛡️ Exception Handling

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.

📝 String Functions (Using Standard Library)

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.

🔥 The (EMIT) Directive - C++ Interoperability

Breaking Down Language Barriers

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

How It Works

{$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++.

💡 Real-World Examples

Using C++ Standard Library

{$INCLUDE_HEADER '<algorithm>'}

function ReverseString(const AText: string): string;
begin
  (*EMIT
    std::string result = AText;
    std::reverse(result.begin(), result.end());
    return result;
  *)
end;

File System Operations

{$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;

High-Performance Math

{$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;

Integrating C Libraries

{$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;

🎯 Why This Matters

Traditional Pascal has been an island - isolated from the rich C/C++ ecosystem. JetPascal changes that:

  1. 🚫 No More Wrappers: Don't write complex FFI wrappers - just use (*EMIT*) and call the C++ API directly
  2. 📦 Static Linking: Link C/C++ libraries statically for single-file deployment (difficult in traditional Delphi)
  3. ⚡ Zero Overhead: It's not FFI - it's native C++ code generation
  4. 📈 Gradual Optimization: Write in Pascal, profile, optimize hotspots with C++
  5. 🎓 Learn One, Use All: Learn Pascal syntax, get access to 40+ years of C/C++ libraries

When to Use (EMIT)

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

📦 Example: Using a C++ Library

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. 🚀

🛠️ Building from Source

Prerequisites

  • 🔧 RAD Studio / Delphi 12.3 (tested on Windows 11)
  • 📦 JetPascal Release - Download from releases to get the res folder 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.

Steps

  1. 📥 Clone the repository:

    git clone https://github.com/tinyBigGAMES/JetPascal.git
    cd JetPascal
  2. 📦 Get the res folder:

    • Download the latest release from GitHub
    • Extract the res folder 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!

  3. 🔨 Open in Delphi:

    • Navigate to src folder
    • Open: JetPascal - Accelerate Your Code!.groupproj
    • This loads all projects in the IDE
  4. ⚙️ Compile each project:

    • Jet.dproj - Command-line interface (produces Jet.exe)
    • JPTester.dproj - Test runner (produces JPTester.exe)
    • JPBench_Delphi.dproj - Performance benchmarks (Delphi)
  5. ✅ Run tests:

    JPTester.exe

📝 Notes

  • Tested with Delphi 12.3 on Windows 11
  • Everything you need is included - no external dependencies
  • The res folder in releases contains all the binary tools
  • Output goes to bin folder

📂 Project Structure

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

🏗️ Technical Details

Architecture

JetPascal uses a polymorphic wrapper architecture:

  1. 📖 Parser: Uses DelphiAST to parse Pascal source code into an AST
  2. 🔄 Preprocessor: Processes directives like (*EMIT*) and {$INCLUDE_HEADER}
  3. 🎯 Transpiler: Walks the AST, creating wrapper objects for each construct (~200 lines)
  4. 🧩 Wrappers: Self-contained classes that generate C++ code for their construct
  5. 📝 Code Generator: Emits clean, readable C++ code
  6. ⚙️ Zig Compiler: Compiles C++ to native code using Clang backend

Why C++ as Target?

  • 🔄 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

Why Zig Build System?

  • 🔧 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

🎨 Language Philosophy

JetPascal follows these principles:

  1. 📝 Pascal First: Clean Pascal syntax is the primary interface
  2. 💪 C++ When Needed: Drop to C++ with (*EMIT*) for power features
  3. ⚡ Performance: Generate efficient C++ that compiles to fast native code
  4. 🔄 Compatibility: Stay close to standard Pascal/Object Pascal semantics
  5. ✨ Simplicity: Avoid unnecessary complexity in the language design
  6. 🔧 Extensibility: Easy to add new features via wrapper architecture
  7. 🎯 Total Control: Compiler directives give complete build control

🤝 Contributing

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

📜 License

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.

🔗 Links


⚡ JetPascal™ - Accelerate Your Code! ⚡

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

About

JetPascal - Accelerate Your Code! 🚀 A next-generation Pascal-to-C++ transpiler that turns your Delphi/Pascal code into blazing-fast native executables. Built with a clean polymorphic architecture that emits modern C++ code, then compiles it using the Zig toolchain for cross-platform deployment.

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Languages