A complete CPaskal program compiles to C++23, then to a native x86_64 executable via Zig/Clang. Everything you need ships in one ZIP.
module exe demo; @target x86_64_windows; // Bind to C library routine clink c_abs(const n: int32): int32; external "c" name "abs"; type Point = record x: float64; y: float64; end; routine distance(a: Point; b: Point): float64; var dx: float64; dy: float64; begin dx := a.x - b.x; dy := a.y - b.y; return cpp("std::sqrt(dx*dx + dy*dy)"); end; begin var a: Point = Point(x: 0.0, y: 0.0); var b: Point = Point(x: 3.0, y: 4.0); println("Distance: {}", distance(a, b)); println("abs(-42) = {}", c_abs(-42)); end.
$ cpas demo -r
CPaskal CLI v0.1.0
Parsing demo.cpas...
Analyzing...
Generating C++23...
Building demo...
Build succeeded.
Running demo.exe...
Distance: 5
abs(-42) = 42
Familiar syntax, explicit types, full control. These examples show CPaskal's core features.
// Explicit-width types -- no ambiguous "integer" var count: int32 = 0; var big: int64 = 9999999999; var byte: uint8 = 255; var pi: float64 = 3.14159; var flag: boolean = true; var name: string = "CPaskal"; var wname: wstring = w"Unicode"; // Pointers with typed syntax var p: pointer to int32 = address of count; println("value = {}", p^); // dereference // Choices (enums) with explicit values type Color = choices(red, green, blue = 5, alpha); var c: Color = Color.blue; // Routine types (function pointers) type BinOp = routine(x: int32; y: int32): int32; var op: BinOp = add; println("result = {}", op(3, 4));
// Records with inheritance, packing, alignment type Base = record x: int32; y: int32; end; Derived = record(Base) z: int32; end; Packed = record packed a: int8; b: int32; end; // Overlays (C unions) Value = overlay asInt: int64; asFloat: float64; end; // Bit fields for hardware/protocol work StatusReg = record ready: uint32 : 1; mode: uint32 : 3; data: uint32 : 8; end; // Record literals -- named initialization var pt: Base = Base(x: 42, y: 99);
// if/then/else with end if x > 0 then println("positive"); else println("non-positive"); end; // for with to/downto for i := 1 to 10 do total += i; end; // while loop while count < 100 do count += 1; end; // repeat..until repeat count += 1; until count >= 10; // match with ranges and multi-labels match value of 0: println("zero"); 1, 2, 3: println("low"); 4..10: println("mid"); else println("high"); end;
// Four module kinds module exe myapp; // executable module dll mylib; // shared library (DLL/SO) module lib mystaticlib;// static library module unit myutils; // importable unit // Import and use with full qualification import myutils; println("version = %d", myutils.UTIL_VERSION); println("add = %d", myutils.util_add(3, 4)); // Public/private visibility public const VERSION: int32 = 1; const SECRET: int32 = 42; // private public routine add(a: int32; b: int32): int32; begin return a + b; end; // Module lifecycle initialize println("starting up..."); end; finalize println("shutting down..."); end;
// guard/except/finally -- catches software AND hardware exceptions guard result := a div b; except println("error: code={}, msg={}", exccode(), excmsg()); finally cleanup(); end; // Throw with message or code throw("something went wrong"); throwcode(404, "resource not found"); // Hardware exceptions caught automatically guard x := 10 div 0; // divide by zero except println("caught: {}", excmsg()); // prints: "Divide by zero" end; // Exception propagation across modules guard myutils.dangerous_operation(); except println("caught from unit: {}", excmsg()); end;
// External clause -- bind to any C library routine clink abs_val(const n: int32): int32; external "c" name "abs"; // Windows API routine clink GetTick(): uint64; external "kernel32" name "GetTickCount64"; // Third-party library via const const RAYLIB: string = "raylib"; routine clink InitWindow(w: int32; h: int32; title: pointer); external RAYLIB; // Raw C++ injection cppstart header #include <cmath> cppend // Inline C++ expressions var sq: float64 = cpp("std::sqrt(2.0)"); // Conditional compilation for platform code @ifdef TARGET_WIN64 println("tick: {}", GetTick()); @endif
// Built-in unit testing framework module exe mathlib; @unittestmode on; routine add(a: int32; b: int32): int32; begin return a + b; end; end. // Test blocks appear after end. test "add returns correct sum" begin asserteq(5, add(2, 3)); asserteq(-2, add(-5, 3)); end; test "add handles zero" begin asserteq(0, add(0, 0)); asserttrue(add(1, -1) = 0); end;
Clean syntax, explicit types, full control over memory and ABI. No hidden complexity.
external clause. Produce C-compatible DLLs and static libraries that Python, Rust, Go, C# and any other language can call.cppstart/cppend blocks and cpp() expressions.guard/except/finally catches both software exceptions and hardware faults like divide-by-zero and access violations. Propagates across module boundaries.exe, dll, lib, unit. Public/private visibility. Full module qualification eliminates name collisions. Initialize/finalize lifecycle hooks..cpas module.The AST is the single source of truth. Each stage enriches it, codegen emits C++23, and Zig/Clang compiles to native.
.cpas source. Keywords and all 16 primitive types are dynamically registered with their C++23 mappings. Nothing hardcoded.zig.exe bundles Clang and its own build system into a single tool. It compiles the C++23 output to the target platform (Win64 or Linux64) entirely from Windows. No separate toolchain installation required.The C boundary is paper-thin. Bind to any C library with a single declaration. Produce DLLs and static libraries the rest of the world can call.
// Bind to libc routine clink toupper(const c: int32): int32; external "c" name "toupper"; // Bind to raylib via CImporter-generated unit import raylib; raylib.InitWindow(800, 600, cstr("Hello")); // Bind to Windows API @ifdef TARGET_WIN64 routine clink GetTick(): uint64; external "kernel32" name "GetTickCount64"; @endif // Bind to Linux API @ifdef TARGET_LINUX64 routine clink getpid(): int32; external "c" name "getpid"; @endif
// Build a DLL any language can call module dll mathlib; public routine clink add( a: int32; b: int32): int32; begin return a + b; end; public routine clink factorial( n: int32): int32; var result: int32 = 1; i: int32; begin for i := 1 to n do result *= i; end; return result; end; end. // Result: mathlib.dll with standard C ABI // Callable from Python, Rust, C#, Java...
The CImporter tool reads C header files and auto-generates CPaskal import units. It uses tinycc for preprocessing, then translates types, constants, and function declarations to .cpas syntax. Binding to raylib, SDL3, SQLite, or any C library is one command away.
CPaskal is a systems programming language. It belongs in the same conversation as C, C++, Rust, and Zig.
Infographic, walkthroughs, and a deep-dive podcast into the language design.
No SDK, no package manager, no setup wizard. Unzip and go.
cpas compiler, the Zig/Clang toolchain, and the C++23 runtime. No installers, no SDKs, no setup. You're ready to compile.