Transpiler
What purrc emits — every gen/ example, .purr beside its generated C++.
purrc is a transpiler: it compiles a .purr program to modern C++ — the .gen.cpp shown on the right — which is then built at -O3 -march=native into a loadable module the cheatah runtime runs. The whole program is emitted inside a namespace cheatah_program, where each module gets its own short alias (io::, ndarray::, …) and the exported entry point is a one-line extern "C" trampoline.
These are the programs in the repository's gen/ folder; regenerate them with bash gen/generate.sh to see how a language change moves the output.
fizzbuzz.purr
Ranges, if, floor division //, and string building.
# Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
# Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
# FizzBuzz — ranges, `if`, floor division `//`, and string building. cheatah has no
# `%`, so divisibility is `i // n * n == i`.
import io
for i in range(1, 21) {
let out = ""
if i // 3 * 3 == i { out = out + "Fizz" }
if i // 5 * 5 == i { out = out + "Buzz" }
if out == "" { out = io.str(i) }
io.print(out)
}// Generated by purrc — do not edit.
#include "cheatah.hpp"
#include "io.hpp"
namespace cheatah_program {
namespace builtins = ::cheatah::builtins;
namespace io = ::cheatah::io;
void purr_main() {
for (long long i = 1LL; i < 21LL; ++i) {
auto out = std::string("");
if (((builtins::floordiv(i, 3LL) * 3LL) == i)) {
out += "Fizz";
}
if (((builtins::floordiv(i, 5LL) * 5LL) == i)) {
out += "Buzz";
}
if ((out == std::string(""))) {
out = io::str(i);
}
io::print(out);
}
}
} // namespace cheatah_program
PURR_EXPORT void purr_main() { cheatah_program::purr_main(); }http_response.purr
A +-chain self-append lowers to one chained ((head += a) += b) += c; — no temporary per piece.
# Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
# Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
# Build a small HTTP response. Shows the in-place string self-append codegen:
# `head = head + ... + ...` lowers to a single chained `((head += a) += b) += c;`
# with no intermediate std::string — look for it in http_response.gen.cpp.
import io
fn response(status, ctype, body) {
let nl = "\n"
let head = "HTTP/1.1 " + status + nl
head = head + "Content-Type: " + ctype + nl
head = head + "Content-Length: " + io.str(len(body)) + nl
head = head + "Connection: close" + nl + nl
return head + body
}
io.print(response("200 OK", "text/plain", "hello, cheatah"))// Generated by purrc — do not edit.
#include "cheatah.hpp"
#include "io.hpp"
namespace cheatah_program {
namespace builtins = ::cheatah::builtins;
namespace io = ::cheatah::io;
static auto response(builtins::Value auto&& status, builtins::Value auto&& ctype, builtins::Value auto&& body) {
auto nl = std::string("\n");
auto head = ((std::string("HTTP/1.1 ") + builtins::str(status)) + builtins::str(nl));
((head += "Content-Type: ") += ctype) += nl;
((head += "Content-Length: ") += io::str(builtins::len(body))) += nl;
((head += "Connection: close") += nl) += nl;
return (head + body);
}
void purr_main() {
io::print(response(std::string("200 OK"), std::string("text/plain"), std::string("hello, cheatah")));
}
} // namespace cheatah_program
PURR_EXPORT void purr_main() { cheatah_program::purr_main(); }grades.purr
A struct with a method, a list, and method-call (UFCS) syntax.
# Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
# Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
# A `struct` with a method, a `list` of them, and method-call (UFCS) syntax.
import io
struct Student {
name: str
score: float
fn grade(self) {
if self.score >= 90.0 { return "A" }
if self.score >= 80.0 { return "B" }
return "C"
}
}
let roster = [
Student("Ada", 95.0),
Student("Linus", 82.0),
Student("Grace", 78.0)
]
for s in roster {
io.print(s.name + ": " + s.grade())
}// Generated by purrc — do not edit.
#include "cheatah.hpp"
#include "io.hpp"
namespace cheatah_program {
namespace builtins = ::cheatah::builtins;
namespace io = ::cheatah::io;
struct Student {
std::string name;
double score;
auto grade() const {
if (((*this).score >= 90.0)) {
return std::string("A");
}
if (((*this).score >= 80.0)) {
return std::string("B");
}
return std::string("C");
}
void cheatah_pretty_print(std::ostream& os_, long long indent_) const {
os_ << "Student(\n";
os_ << std::string(indent_ + 4, ' ') << "name = ";
os_ << this->name;
os_ << ",\n";
os_ << std::string(indent_ + 4, ' ') << "score = ";
os_ << this->score;
os_ << "\n";
os_ << std::string(indent_, ' ') << ")";
}
};
inline std::ostream& operator<<(std::ostream& os_, const Student& v_) {
return os_ << "Student(" << "name=" << v_.name << ", score=" << v_.score << ")";
}
void purr_main() {
auto roster = std::vector{
Student{std::string("Ada"), 95.0},
Student{std::string("Linus"), 82.0},
Student{std::string("Grace"), 78.0}
};
for (auto& s : roster) {
io::print(((builtins::str(s.name) + std::string(": ")) + builtins::str(s.grade())));
}
}
} // namespace cheatah_program
PURR_EXPORT void purr_main() { cheatah_program::purr_main(); }palette.purr
A scoped enum with match/case — the enum class lowering, with a generated operator<<.
# Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
# Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
# A scoped `enum` + `match`/`case`. Shows the enum-class codegen.
import io
enum Color { RED, GREEN, BLUE }
fn to_hex(c) {
match c {
case Color.RED { return "#ff0000" }
case Color.GREEN { return "#00ff00" }
case Color.BLUE { return "#0000ff" }
}
return "#000000"
}
for c in [Color.RED, Color.GREEN, Color.BLUE] {
io.print(c, "->", to_hex(c))
}// Generated by purrc — do not edit.
#include "cheatah.hpp"
#include <ostream>
#include "io.hpp"
namespace cheatah_program {
namespace builtins = ::cheatah::builtins;
namespace io = ::cheatah::io;
enum class Color {
RED,
GREEN,
BLUE,
};
inline std::ostream& operator<<(std::ostream& os_, Color v_) {
if (v_ == Color::RED) return os_ << "Color.RED";
if (v_ == Color::GREEN) return os_ << "Color.GREEN";
if (v_ == Color::BLUE) return os_ << "Color.BLUE";
return os_ << "Color(" << static_cast<long long>(v_) << ")";
}
static auto to_hex(builtins::Value auto&& c) {
{
auto __match_0 = c;
if (__match_0 == Color::RED) {
return std::string("#ff0000");
}
else if (__match_0 == Color::GREEN) {
return std::string("#00ff00");
}
else if (__match_0 == Color::BLUE) {
return std::string("#0000ff");
}
}
return std::string("#000000");
}
void purr_main() {
for (auto& c : std::vector{Color::RED, Color::GREEN, Color::BLUE}) {
io::print(c, "->", to_hex(c));
}
}
} // namespace cheatah_program
PURR_EXPORT void purr_main() { cheatah_program::purr_main(); }vectors.purr
ndarray arrays through linalg routines — the numeric core, with per-module namespace aliases (ndarray::, linalg::).
# Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
# Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
# A tiny numeric program — `ndarray` arrays into `linalg` routines.
import io
import ndarray
import linalg
let a = ndarray.array([[2.0, 1.0], [1.0, 3.0]])
let b = ndarray.array([1.0, 2.0])
io.print("solve A x = b ->", ndarray.to_string(linalg.solve(a, b)))
io.print("det(A) ->", linalg.det(a))
io.print("eigenvalues ->", ndarray.to_string(linalg.eigvalsh(a)))// Generated by purrc — do not edit.
#include "cheatah.hpp"
#include "io.hpp"
#include "linalg.hpp"
#include "ndarray.hpp"
namespace cheatah_program {
namespace builtins = ::cheatah::builtins;
namespace io = ::cheatah::io;
namespace linalg = ::cheatah::linalg;
namespace ndarray = ::cheatah::ndarray;
void purr_main() {
auto a = ndarray::array(std::vector{std::vector{2.0, 1.0}, std::vector{1.0, 3.0}});
auto b = ndarray::array(std::vector{1.0, 2.0});
io::print("solve A x = b ->", ndarray::to_string(linalg::solve(a, b)));
io::print("det(A) ->", linalg::det(a));
io::print("eigenvalues ->", ndarray::to_string(linalg::eigvalsh(a)));
}
} // namespace cheatah_program
PURR_EXPORT void purr_main() { cheatah_program::purr_main(); }numerics.purr
Four modules linked into one program: math, ndarray and linalg each lower to an #include and a short namespace alias, solving a 3×3 system on the SIMD core.
# Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
# Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
# The numeric core, several modules linked into one program: each `import` lowers to its own
# #include and a short namespace alias (math::, ndarray::, linalg::) in the generated C++.
import io
import math
import ndarray
import linalg
# A 3x3 system A x = b, built from nested lists (ndarray reads the shape off the nesting).
let A = ndarray.array([[3.0, 2.0, -1.0],
[2.0, -2.0, 4.0],
[-1.0, 0.5, -1.0]])
let b = ndarray.array([1.0, -2.0, 0.0])
# Solve with the SIMD linalg core, then check the residual norm ‖A x - b‖.
let x = linalg.solve(A, b)
let residual = linalg.norm(ndarray.sub(linalg.matmul(A, x), b))
io.print("x =", x)
io.print("residual =", residual)
io.print("det(A) =", linalg.det(A))
io.print("hypot =", math.sqrt(3.0 * 3.0 + 4.0 * 4.0))// Generated by purrc — do not edit.
#include "cheatah.hpp"
#include "io.hpp"
#include "linalg.hpp"
#include "math.hpp"
#include "ndarray.hpp"
namespace cheatah_program {
namespace builtins = ::cheatah::builtins;
namespace io = ::cheatah::io;
namespace linalg = ::cheatah::linalg;
namespace math = ::cheatah::math;
namespace ndarray = ::cheatah::ndarray;
void purr_main() {
auto A = ndarray::array(std::vector{
std::vector{3.0, 2.0, (-1.0)},
std::vector{2.0, (-2.0), 4.0},
std::vector{(-1.0), 0.5, (-1.0)}
});
auto b = ndarray::array(std::vector{1.0, (-2.0), 0.0});
auto x = linalg::solve(A, b);
auto residual = linalg::norm(ndarray::sub(linalg::matmul(A, x), b));
io::print("x =", x);
io::print("residual =", residual);
io::print("det(A) =", linalg::det(A));
io::print("hypot =", math::sqrt(((3.0 * 3.0) + (4.0 * 4.0))));
}
} // namespace cheatah_program
PURR_EXPORT void purr_main() { cheatah_program::purr_main(); }shapes.purr
An interface lowers to a C++20 concept (a static_assert checks every struct that fulfills it), and an interface-typed parameter constrains the generated template — no inheritance.
# Copyright (c) 2026 BigBrain LLC. MIT-licensed (see LICENSE).
# Original work; see ACKNOWLEDGMENTS.md for the open-source ideas we build upon.
# Records with behavior. A `struct` lowers to a C++ struct; an `interface` lowers to a C++20
# concept, and an interface-typed parameter (`s: Shape`) constrains the generated template —
# checked at compile time, with no inheritance and no runtime dispatch.
import io
interface Shape {
fn area(self)
}
struct Circle: Shape {
r: float
fn area(self) { return 3.14159 * self.r * self.r }
}
struct Rect: Shape {
w: float
h: float
fn area(self) { return self.w * self.h }
}
# Constrained by the Shape concept: any record with an `area(self) -> float` fits.
fn report(s: Shape) {
io.print("area =", s.area())
}
let c = Circle({.r = 2.0})
let r = Rect({.w = 3.0, .h = 4.0})
report(c)
report(r)// Generated by purrc — do not edit.
#include "cheatah.hpp"
#include "io.hpp"
namespace cheatah_program {
namespace builtins = ::cheatah::builtins;
namespace io = ::cheatah::io;
template <typename Self>
concept Shape =
requires(Self& self) { self.area(); };
struct Circle {
double r;
auto area() const {
return ((3.14159 * (*this).r) * (*this).r);
}
void cheatah_pretty_print(std::ostream& os_, long long indent_) const {
os_ << "Circle(\n";
os_ << std::string(indent_ + 4, ' ') << "r = ";
os_ << this->r;
os_ << "\n";
os_ << std::string(indent_, ' ') << ")";
}
};
static_assert(Shape<Circle>, "Circle must fulfill Shape");
inline std::ostream& operator<<(std::ostream& os_, const Circle& v_) {
return os_ << "Circle(" << "r=" << v_.r << ")";
}
struct Rect {
double w;
double h;
auto area() const {
return ((*this).w * (*this).h);
}
void cheatah_pretty_print(std::ostream& os_, long long indent_) const {
os_ << "Rect(\n";
os_ << std::string(indent_ + 4, ' ') << "w = ";
os_ << this->w;
os_ << ",\n";
os_ << std::string(indent_ + 4, ' ') << "h = ";
os_ << this->h;
os_ << "\n";
os_ << std::string(indent_, ' ') << ")";
}
};
static_assert(Shape<Rect>, "Rect must fulfill Shape");
inline std::ostream& operator<<(std::ostream& os_, const Rect& v_) {
return os_ << "Rect(" << "w=" << v_.w << ", h=" << v_.h << ")";
}
static auto report(Shape auto&& s) {
io::print("area =", s.area());
}
void purr_main() {
auto c = Circle{.r = static_cast<double>(2.0)};
auto r = Rect{.w = static_cast<double>(3.0), .h = static_cast<double>(4.0)};
report(c);
report(r);
}
} // namespace cheatah_program
PURR_EXPORT void purr_main() { cheatah_program::purr_main(); }