TL;DR
JetPascal v0.2.0 is the Pascal-to-C++ transpiler that breaks down the traditional barrier between Pascal and the C++ ecosystem. Mix Pascal and C++ freely, include headers directly, link libraries with a single directive, and access 40+ years of C++ libraries without writing wrapper code. Complete Pascal language support, built-in unit testing, cross-platform compilation, and a revolutionary smart token architecture.
🎯 The Game-Changing Feature
Zero-Friction C++ Ecosystem Access
For decades, Pascal developers faced a critical barrier: accessing C++ libraries required DLL wrappers, FFI bindings, and constant maintenance overhead. JetPascal eliminates this completely.
✅ Unknown tokens = C++ - Don't recognize it? Emit it as C++
✅ Direct header inclusion - #include_header '<vector>' brings C++ into scope
✅ Unrestricted C++ blocks - #startcpp/#endcpp for ANY C++ code
✅ Static library linking - #link 'raylib' - done
✅ Seamless token mixing - Pascal and C++ in the same expression
✅ No wrappers needed - Zero FFI overhead, zero binding maintenance
🔥 What's New in v0.2.0
The "Living in C++" Philosophy
JetPascal operates at the C++ boundary at all times:
- Pascal as Syntactic Sugar - Pascal transpiles to C++23
- Transparent Fallthrough - Unknown tokens emit as raw C++
- C++ Semantics - Leverage C++23 features for Pascal behavior
- Zero Overhead - No FFI, no marshaling, direct code generation
Example - Mixing Pascal and C++:
program MixedDemo;
#include_header '<cmath>'
var
LValue: Integer;
LResult: Double;
begin
// Pure Pascal
LValue := 10;
WriteLn('Pascal: Value = ', LValue);
// Pure C++ - std::cout is not a Pascal token, emitted as C++!
std::cout << "C++: Hello!" << std::endl;
// Mixed: Pascal WriteLn with C++ expression
WriteLn('Square root: ', std::sqrt(16.0));
// Mixed: C++ expression in Pascal assignment
LResult := std::pow(2.0, 8.0);
WriteLn('2^8 = ', LResult);
end.This just works. No wrappers. No bindings. Pascal calls C++, C++ calls Pascal - seamlessly.
Unrestricted C++ Blocks - Complete Freedom
Need to write complex C++ code? Use #startcpp/#endcpp:
program AdvancedCpp;
#include_header '<vector>'
#include_header '<algorithm>'
var
LSum: Integer;
begin
LSum := 0;
#startcpp
// ANY C++ code - ZERO restrictions!
std::vector<int> numbers = {5, 2, 8, 1, 9};
// Sort with C++ STL
std::sort(numbers.begin(), numbers.end());
// Lambda expressions
auto multiply = [](int a, int b) { return a * b; };
std::cout << "10 * 5 = " << multiply(10, 5) << std::endl;
// Calculate sum for Pascal variable
for (const auto& n : numbers) {
LSum += n; // Modifying Pascal variable from C++!
}
// Range-based for
std::cout << "Sorted: ";
for (const auto& n : numbers) {
std::cout << n << " ";
}
std::cout << std::endl;
#endcpp
WriteLn('Sum from C++: ', LSum); // Using the value C++ calculated
end.C++ lambdas. STL algorithms. Range-based loops. Templates. All available.
Static Library Linking - Single Executable Deployment
The raylib example that changes everything:
program RaylibGame;
#optimization releasesmall
#include_header '"raylib.h"'
#link 'raylib'
#link 'gdi32'
#link 'opengl32'
#link 'winmm'
begin
InitWindow(800, 450, "JetPascal + raylib!");
SetTargetFPS(60);
while not WindowShouldClose() do
begin
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
EndDrawing();
end;
CloseWindow();
end.This is a complete, working game window that compiles to a single .exe with raylib statically linked!
- ✅ No wrapper code
- ✅ No DLL dependencies
- ✅ Direct C++ function calls
- ✅ Single-file deployment
- ✅ Production-ready
Complete Pascal Language Support
All the Pascal features you expect:
Basic Types
var
LInt: Integer; // 32-bit signed
LInt64: Int64; // 64-bit signed
LUInt: UInt64; // 64-bit unsigned
LCard: Cardinal; // 32-bit unsigned
LWord: Word; // 16-bit unsigned
LByte: Byte; // 8-bit unsigned
LBool: Boolean; // Boolean
LChar: Char; // Character
LSingle: Single; // 32-bit float
LDouble: Double; // 64-bit float
LStr: String; // Unicode stringPointers and Memory
var
LPtr: PInteger;
LValue: Integer;
begin
// Allocate
New(LPtr);
LPtr^ := 42;
WriteLn('Value: ', LPtr^);
Dispose(LPtr);
// Manual memory management
GetMem(LPtr, SizeOf(Integer));
LPtr^ := 100;
WriteLn('Value: ', LPtr^);
FreeMem(LPtr);
// Zero-filled allocation
LPtr := AllocMem(SizeOf(Integer));
WriteLn('Zero-filled: ', LPtr^);
FreeMem(LPtr);
end.Arrays
type
TStaticArray = array[1..10] of Integer;
TNegativeIndex = array[-5..5] of Integer;
TMatrix = array[1..3, 1..3] of Double;
var
LArr: TStaticArray;
LNeg: TNegativeIndex;
LMatrix: TMatrix;
begin
// Regular arrays
LArr[5] := 100;
// Negative indices work!
LNeg[-3] := 42;
LNeg[0] := 0;
LNeg[3] := 42;
// Multi-dimensional
LMatrix[2, 3] := 3.14;
end.Records
type
TPoint = record
X: Integer;
Y: Integer;
end;
TPerson = record
Name: String;
Age: Integer;
end;
var
LPoint: TPoint;
LPerson: TPerson;
begin
LPoint.X := 10;
LPoint.Y := 20;
LPerson.Name := 'Alice';
LPerson.Age := 30;
end.Records map directly to C++ structs - no overhead, no translation.
Control Flow
var
LI: Integer;
begin
// If/then/else
if LI > 0 then
WriteLn('Positive')
else if LI < 0 then
WriteLn('Negative')
else
WriteLn('Zero');
// For loops (to/downto)
for LI := 1 to 10 do
WriteLn(LI);
for LI := 10 downto 1 do
WriteLn(LI);
// While loop
while LI < 100 do
begin
Inc(LI);
if LI = 50 then
break;
end;
// Repeat/until
repeat
Dec(LI);
if LI < 25 then
continue;
WriteLn(LI);
until LI <= 0;
end.Exception Handling
var
LMsg: String;
begin
try
WriteLn('Before exception');
RaiseException('Something went wrong!');
WriteLn('After exception - not reached');
except
LMsg := GetExceptionMessage();
WriteLn('Caught: ', LMsg);
end;
try
WriteLn('In try block');
finally
WriteLn('Finally always executes');
end;
end.C++ exceptions under the hood - proper cleanup, proper unwinding.
Functions and Procedures
function Add(const A, B: Integer): Integer;
begin
Result := A + B;
end;
procedure Swap(var A, B: Integer);
var
LTemp: Integer;
begin
LTemp := A;
A := B;
B := LTemp;
end;
function Factorial(const N: Integer): Integer;
begin
if N <= 1 then
Result := 1
else
Result := N * Factorial(N - 1);
end;Units - Modular Programming
UnitMath.pas:
unit UnitMath;
interface
function Add(const A, B: Integer): Integer;
function Multiply(const A, B: Integer): Integer;
implementation
function Add(const A, B: Integer): Integer;
begin
Result := A + B;
end;
function Multiply(const A, B: Integer): Integer;
begin
Result := A * B;
end;
end.Program.pas:
program MyApp;
uses
UnitMath;
begin
WriteLn('10 + 20 = ', Add(10, 20));
WriteLn('10 * 20 = ', Multiply(10, 20));
end.Built-in Unit Testing Framework
Professional testing built into the language:
#unittestmode on
program MathTests;
function Add(const A, B: Integer): Integer;
begin
Result := A + B;
end;
function Multiply(const A, B: Integer): Integer;
begin
Result := A * B;
end;
begin
WriteLn('Main program');
end.
test 'Addition works correctly'
begin
AssertEqual(4, Add(2, 2));
AssertEqual(10, Add(7, 3));
AssertEqual(-5, Add(-2, -3));
end;
test 'Multiplication works correctly'
begin
AssertEqual(20, Multiply(4, 5));
AssertEqual(0, Multiply(5, 0));
AssertEqual(-15, Multiply(3, -5));
end;Features:
#unittestmode ondirectivetest 'description'blocksAssertEqual(expected, actual)Assert(condition)- Integrated test runner
- Clean output
Compiler Directives - Total Build Control
Everything configured in your Pascal source - no external build files:
program MyApp;
// Optimization
#optimization releasefast // debug, releasesafe, releasefast, releasesmall
// Cross-compilation
#target x86_64-linux // native, x86_64-windows, x86_64-linux,
// aarch64-macos, aarch64-linux, wasm32-wasi
// Application type
#apptype gui // console, gui
// Search paths
#unit_path '../units'
#include_path '../include'
#library_path '../lib'
// C++ integration
#include_header '<vector>'
#include_header '"mylib.h"'
#link 'raylib'
// ABI control
#abi c // c, cpp
// Preprocessor
#define DEBUG
#ifdef DEBUG
WriteLn('Debug mode');
#endif
begin
// Your code
end.Supported Targets:
native- Current platformx86_64-windows- Windows 64-bitx86_64-linux- Linux 64-bitaarch64-macos- macOS ARM64 (Apple Silicon)aarch64-linux- Linux ARM64wasm32-wasi- WebAssembly (experimental)
Optimization Levels:
debug- Fast compile, full debug inforeleasesafe- Optimized with safety checksreleasefast- Maximum speedreleasesmall- Minimum size
C++ Operators
var
LValue: Integer;
LX, LY: Integer;
begin
// Compound assignment
LValue := 10;
LValue += 5; // 15
LValue -= 3; // 12
LValue *= 2; // 24
LValue /= 4; // 6
// Increment/decrement
WriteLn(++LValue); // Prefix: 7
WriteLn(LValue++); // Postfix: 7 (then becomes 8)
WriteLn(--LValue); // Prefix: 7
WriteLn(LValue--); // Postfix: 7 (then becomes 6)
// Bitwise operations
LX := 0b1100;
LY := 0b1010;
WriteLn(LX & LY); // AND: 0b1000
WriteLn(LX | LY); // OR: 0b1110
WriteLn(LX ^ LY); // XOR: 0b0110
WriteLn(~LX); // NOT
WriteLn(LX << 2); // Shift left
WriteLn(LX >> 1); // Shift right
end.System Functions
Built-in functions for common operations:
var
LPtr: Pointer;
LSize: Integer;
LValue: Integer;
begin
// Memory
LPtr := AllocMem(100); // Allocate zero-filled
FreeMem(LPtr); // Free memory
GetMem(LPtr, 200); // Allocate
ReallocMem(LPtr, 300); // Reallocate
LSize := SizeOf(Integer); // Size of type
// Ordinal
LValue := Ord('A'); // Get ordinal value
Inc(LValue); // Increment
Dec(LValue); // Decrement
// Command line
WriteLn('Arg count: ', ParamCount());
WriteLn('Arg 1: ', ParamStr(1));
// I/O
WriteLn('Hello, World!');
Write('No newline');
WriteLn('Multiple ', 'arguments ', 123, ' ', 3.14);
// Exceptions
RaiseException('Error message');
WriteLn(GetExceptionMessage());
end.Full Conditional Compilation
Complete C++ preprocessor support:
program Conditionals;
#define VERSION 2
#define FEATURE_X
#ifdef FEATURE_X
WriteLn('Feature X enabled');
#else
WriteLn('Feature X disabled');
#endif
#if VERSION >= 2
WriteLn('Version 2 or higher');
#endif
#ifndef FEATURE_Y
WriteLn('Feature Y not defined');
#endif
#undef FEATURE_X
begin
WriteLn('Conditional compilation works!');
end.🏗️ Revolutionary Architecture
Smart Token System
JetPascal's architecture is fundamentally different from traditional compilers:
Traditional Compilers:
- Monolithic parser
- Giant switch statements
- "God Object" antipattern
- Hard to extend
- Difficult to maintain
JetPascal's Smart Tokens:
- Self-contained token objects
- Each token handles its own parsing
- Each token emits its own C++ code
- Factory pattern for extensibility
- Minimal core (150-200 lines)
- Polymorphic dispatch
Adding a new feature:
- Create a new smart token class
- Register it in
JetPascal.Setup.pas - Done!
Example - Adding the Inc function required ONE line:
RegisterSmartToken('inc', TIncToken);The TIncToken class handles everything:
- Parsing the
Inc(Variable)syntax - Validating parameters
- Emitting C++ code
++Variable - Edge cases and error handling
"Just Works" Principle
New features integrate automatically with existing infrastructure:
Example: Adding records required ZERO changes to:
- Variable declarations
- Assignments
- Field access
- Function parameters
Why? Because Pascal record syntax maps directly to C++ struct syntax, and JetPascal "lives in C++".
100+ Smart Tokens
Current smart token categories:
System:
- ParamCount, ParamStr
- Ord, Inc, Dec
- SizeOf
Memory:
- New, Dispose
- GetMem, FreeMem
- AllocMem, ReallocMem
Types:
- Integer, Int64, UInt64, Cardinal, Word, Byte
- Boolean, Char
- Single, Double
- String
- Arrays, Records, Pointers
- Enumerations
Control Flow:
- if, then, else
- while, do
- for, to, downto
- repeat, until
- break, continue
Exceptions:
- try, except, finally
- RaiseException
- GetExceptionMessage
I/O:
- WriteLn, Write
Directives:
- All # directives (optimization, target, link, etc.)
- All conditional compilation (#define, #ifdef, etc.)
Unit Testing:
- #unittestmode
- test blocks
- Assert, AssertEqual
🎁 Zig Build System Integration
Everything self-contained - no external dependencies:
- ✅ Zig toolchain included
- ✅ Latest Clang/LLVM compiler
- ✅ C++ standard library
- ✅ Cross-compilation support
- ✅ Optimized build pipeline
- ✅ Static and dynamic linking
- ✅ ~500MB installation - everything you need
Cross-compilation is trivial:
#target x86_64-linuxThat's it. JetPascal + Zig handle everything else.
🚀 Getting Started
Installation
Requirements:
- Windows 10 or later
- ~500MB disk space
- 2GB RAM minimum
Steps:
- Download latest release from GitHub
- Extract to folder (e.g.,
C:\Dev\JetPascal) - Add
binto PATH - Verify:
jet version
Your First Program
jet init HelloWorld
cd HelloWorld
jet build
jet runReal-World Example - raylib Game
jet init MyGame
cd MyGameEdit src/MyGame.pas:
program MyGame;
#optimization releasesmall
#include_header '"raylib.h"'
#link 'raylib'
#link 'gdi32'
#link 'opengl32'
#link 'winmm'
begin
InitWindow(800, 450, "My First Game!");
SetTargetFPS(60);
while not WindowShouldClose() do
begin
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText("It just works!", 200, 200, 20, DARKGRAY);
EndDrawing();
end;
CloseWindow();
end.jet build
jet runYou just created a game window with raylib. Zero wrapper code. Zero bindings.
📚 CLI Reference
jet init <name> [--template <type>] # Create project
jet build # Build current project
jet run # Run compiled program
jet clean # Remove build artifacts
jet zig <args> # Pass through to Zig
jet version # Show version
jet help # Show helpProject templates:
program(default) - Executablelibrary- Shared library (.dll/.so)unit- Static library (.lib/.a)
💡 Why JetPascal Changes Everything
The Old Way (Traditional Pascal)
Want to use a C++ library?
- Find or create a C interface wrapper
- Write Pascal FFI bindings
- Maintain bindings when library updates
- Deal with marshaling overhead
- Handle DLL distribution
- Debug across language boundary
Result: Weeks of work, ongoing maintenance burden
The JetPascal Way
Want to use a C++ library?
#include_header '"library.h"'#link 'library'- Call functions directly
Result: Done. No wrappers. No bindings. No friction.
Real-World Impact
Before JetPascal:
- Pascal developers isolated from C++ ecosystem
- Raylib? Requires wrapper project
- OpenCV? Custom bindings needed
- Boost? Forget about it
With JetPascal:
- Raylib?
#include_header+#link- done - OpenCV? Same approach - works
- Boost? Include and use - no problem
The entire C++ ecosystem is now accessible to Pascal developers.
🎯 The Bottom Line
JetPascal v0.2.0 breaks down the wall between Pascal and C++.
✅ Write Pascal syntax
✅ Include C++ headers
✅ Link C++ libraries
✅ Mix freely in same source
✅ No wrappers needed
✅ No FFI overhead
✅ No binding maintenance
✅ Complete Pascal language
✅ Built-in unit testing
✅ Cross-platform compilation
✅ Smart token architecture
✅ Everything self-contained
Build games. Build utilities. Build applications. Access the entire C++ universe.
📖 Documentation
Comprehensive docs available:
- Vision - Philosophy and design
- User Guide - Installation and CLI
- Programming Guide - Language features and C++ interop
- Reference Guide - Technical reference
🌐 Community
- GitHub: tinyBigGAMES/JetPascal
- Discord: Join our community
- Facebook: JetPascal Group
- Bluesky: @tinybiggames.com
- Issues: Report bugs
🤝 Contributing
JetPascal is open source (BSD 3-Clause License). Contributions welcome!
🔮 What's Next?
JetPascal has the foundation for Pascal/C++ interop. What libraries do YOU want to use? Let us know!
Write Pascal. Access C++. Ship everywhere. 🚀
File Integrity
Files are signed with minisign using this public key:
RWTqBYfsUOCQscb6ZeknLC0On3cvWCVzMzlHamtgXNaDOO4bNs3WCSkV
Copyright © 2025-present tinyBigGAMES™ LLC. All Rights Reserved.