NitroPascal is Object Pascal. It compiles to native binaries via C++23.
NitroPascal is a full-featured Object Pascal compiler built entirely on top of Parse() - the compiler construction toolkit. It exists to prove a point: a complete, production-quality language can be built with Parse() without touching a parser generator, a lexer generator, or a custom pipeline. Every stage - tokenization, Pratt parsing, semantic analysis, C++23 code generation, and native compilation via Zig - is driven through a single Parse() configuration object.
program Hello;
begin
WriteLn('Hello from NitroPascal!');
end.NitroPascal is not a toy. It is a working Pascal compiler that handles programs, procedures, functions, typed variables, arrays, sets, pointers, records, string manipulation, math, and memory management - all the things you would expect from a real Pascal implementation. The generated output is clean C++23, compiled to a native Win64 or Linux64 binary by the Zig/Clang backend that ships with ParseKit.
NitroPascal is the reference showcase for the Parse() Compiler Construction Toolkit. If you want to see what a full language looks like when built on Parse(), this is it. Read the source. Every grammar rule, every semantic check, every code emitter is a Parse() registration call - nothing more.
NitroPascal is actively developed. The foundation is solid and the core language works. More features are being added continuously.
- Program structure -
program,var,const,type,begin..end. - Primitive types -
Integer,Double,Boolean,Char,String - Procedures and functions - full declarations, parameters (
const,var,out),Resultreturn convention - Control flow -
if/then/else,while/do,for/to/downto,repeat/until,case/of,break,continue,exit - Arrays - fixed arrays with arbitrary index bounds, dynamic arrays,
SetLength - Sets - Pascal set types,
Include,Exclude,inoperator - Pointers - typed pointer declarations,
^T,@expr, dereference, pointer type aliases - Records - field declarations, nested records, pass by value/ref/out, functions returning records
- Literals - integer, real, string, char (
#65), hex ($FF), boolean,nil - Intrinsics -
Inc,Dec,Ord,Chr,Succ,Pred,Odd,Assigned,Length,Copy,Pos,UpperCase,LowerCase,Trim,IntToStr,StrToInt,StrToIntDef,StringOfChar,Abs,Sqr,Sqrt,Max,Min,Round,Trunc,New,Dispose - I/O -
WriteLn,Write
- Classes and objects with inheritance and virtual dispatch
- Exception handling (
try/except/finally) - Enumerations
- Units and
usesclause - String escape sequences and extended string handling
- More intrinsics and RTL coverage
- Linux64 cross-compile support
NitroPascal serves two audiences.
If you write Pascal, NitroPascal gives you a path from .pas source to a native binary without a legacy toolchain. Write standard Object Pascal, get a fast, small native executable. Just the NitroPascal compiler and the bundled Zig backend.
If you build languages, NitroPascal is the definitive answer to "can Parse() handle a real language?" Browse src/NitroPascal.Lexer.pas, src/NitroPascal.Grammar.pas, src/NitroPascal.Semantics.pas, and src/NitroPascal.CodeGen.pas. Every feature maps directly to Parse() API calls. There is no magic, no custom parser, no hand-rolled AST infrastructure. If NitroPascal can implement full Pascal on Parse(), your language can too.
NitroPascal is four source files and Parse():
NitroPascal.Lexer.pas - keyword and operator registration
NitroPascal.Grammar.pas - Pratt grammar rules (prefix + infix + statement handlers)
NitroPascal.Semantics.pas - type assignment and symbol resolution rules
NitroPascal.CodeGen.pas - C++23 emitters for every AST node kind
Each file is a set of AParse.Config().Register*() calls. That is the entire compiler. Parse() provides the tokenizer, the Pratt parser engine, the scope-aware semantic walker, the C++23 IR builder, and the Zig compilation backend. NitroPascal provides the language definition.
Pascal source
|
v
+-----------+ tokens +----------+ AST +------------+
| Lexer | --------> | Parser | -----------> | Semantics |
| (Parse()) | | (Parse())| | (Parse()) |
+-----------+ +----------+ +------------+
|
enriched AST (type, scope, decl)
|
v
+-----------+
| CodeGen | --> .h + .cpp
| (Parse()) |
+-----------+
|
v
+---------+
| Zig | --> native binary
+---------+
NitroPascal requires the ParseKit sources to be present as a sibling directory alongside NitroPascal. The Delphi project references ParseKit's source directly. The required layout is:
C:\Dev\ <- or any root you choose
ParseKit\ <- ParseKit repo root (contains src\, bin\, etc.)
NitroPascal\ <- NitroPascal repo root (contains src\, bin\, etc.)
Both repos must share the same parent directory. If they do not, the Delphi project will not compile.
Option 1: Download ParseKit ZIP
Option 2: Git clone
git clone https://github.com/tinyBigGAMES/ParseKit.gitPlace (or clone) it so the folder structure matches the layout above.
Option 1: Download NitroPascal ZIP
Option 2: Git clone
git clone https://github.com/tinyBigGAMES/NitroPascal.gitThe toolchain must be downloaded separately. It contains the Zig compiler and C++ runtime that NitroPascal uses to compile generated code to native binaries. Without it, the pipeline cannot produce binaries.
Download parsekit-toolchain.zip
Unzip the toolchain directly into the root of your NitroPascal directory:
NitroPascal\ <- repo root
bin\ <- toolchain contents go here (zig\, res\, etc.)
src\
...
This is a permanent release entry. The URL will never change. When the toolchain is updated, the same release entry is replaced in place. You always download from the same link.
| Requirement | |
|---|---|
| Host OS | Windows 10/11 x64 |
| Linux target | WSL2 + Ubuntu (wsl --install -d Ubuntu) |
| Delphi | Delphi 11 Alexandria or later (to build from source) |
- Open
src\NitroPascal.groupprojin Delphi - Build all projects in the group (
NitroPascal,Testbed) - The
Testbedproject compiles and runs all tests inbin\res\tests\and prints colour-coded pass/fail results
cd NitroPascal\bin
testbedOr call the compiler programmatically:
uses
NitroPascal;
var
LCompiler: TNitroPascal;
begin
LCompiler := TNitroPascal.Create();
try
LCompiler.SetSourceFile('hello.pas');
LCompiler.SetOutputPath('output');
if LCompiler.Compile(True) then
WriteLn('Done.')
else
WriteLn('Failed: ', LCompiler.GetLastError());
finally
LCompiler.Free();
end;
end;program Showcase;
var
i: Integer;
s: String;
arr: array[1..5] of Integer;
flags: set of (0..7);
function Factorial(const AValue: Integer): Integer;
begin
if AValue <= 1 then
Result := 1
else
Result := AValue * Factorial(AValue - 1);
end;
begin
// Arithmetic and string intrinsics
s := 'Hello, NitroPascal!';
WriteLn(UpperCase(s));
WriteLn('Length: ', IntToStr(Length(s)));
// Arrays (1-based indexing)
for i := 1 to 5 do
arr[i] := i * i;
WriteLn('Squares: ', arr[1], ' ', arr[2], ' ', arr[3], ' ', arr[4], ' ', arr[5]);
// Sets
flags := [1, 3, 5];
Include(flags, 7);
if 3 in flags then
WriteLn('3 is in flags');
// Recursion
for i := 1 to 7 do
WriteLn(IntToStr(i) + '! = ' + IntToStr(Factorial(i)));
end.NitroPascal is an open project. Whether you are fixing a bug, improving documentation, adding a language feature, or writing a new test case, contributions are welcome.
- Report bugs: Open an issue with a minimal reproduction. The smaller the example, the faster the fix.
- Suggest features: Describe the use case first, then the syntax you have in mind. Features that emerge from real problems get traction fastest.
- Submit pull requests: Bug fixes, documentation improvements, new test cases, and well-scoped features are all welcome. Keep changes focused.
- Add tests: The
bin\res\tests\directory contains.pastest files. New tests that cover edge cases or new features are always valuable.
Join the Discord to discuss development, ask questions, and share what you are building.
NitroPascal is built in the open. If it saves you time 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 you are part of
- π¬ Join us on Discord: share what you are building and help shape what comes next
- π Become a sponsor: sponsorship directly funds time spent on the compiler, runtime, and documentation
NitroPascal is licensed under the Apache License 2.0. See LICENSE for details.
Apache 2.0 is a permissive open source license that lets you use, modify, and distribute NitroPascal freely in both open source and commercial projects. You are not required to release your own source code. You can embed NitroPascal into a proprietary product, ship it as part of a commercial tool, or build on top of it without restriction.
The license includes an explicit patent grant, meaning contributors cannot later assert patent claims against you for using their contributions. Attribution is required - keep the copyright notice and license file in place - but beyond that, NitroPascal is yours to build with.
NitroPascalβ’ - A full-featured Object Pascal compiler built on Parse().
Copyright Β© 2025-present tinyBigGAMESβ’ LLC All Rights Reserved.
