BPL is a statically-typed, compiled programming language that transpiles to LLVM IR. It combines the performance and control of systems languages with modern language features, making it ideal for performance-critical applications, systems programming, and educational purposes.
import [IO] from "std/io.bpl";
struct Point {
x: int,
y: int
}
frame main() ret int {
local p: Point;
p.x = 10;
p.y = 20;
IO.log("Hello from BPL!");
return 0;
}- LLVM Backend: Leverages LLVM's world-class optimization and code generation
- Zero-Cost Abstractions: High-level features without runtime overhead
- Manual Memory Management: Direct control over allocations for predictable performance
- Native Compilation: Produces optimized machine code for your platform
- Strong Static Typing: Catch errors at compile-time before they become runtime bugs
- Generics: Write reusable, type-safe code with full monomorphization
- No Null Dereferences: Explicit null handling patterns
- Type Inference: Less verbose where it matters, explicit where it helps
- Object-Oriented: Structs with methods, single and multiple inheritance
- Module System: Organize code with imports and exports
- Exception Handling: Try/catch blocks for robust error management
- Pattern Matching: Type-safe conditional logic
- Process execution: Execute shell commands, check status, and capture output with automatic injection protection
- String Interpolation: Embed expressions in strings with
`Hello ${name}` - Tuples: Multi-value types for clean APIs
- Function Pointers: First-class functions
- Clear Error Messages: Helpful compiler diagnostics with location information
- Built-in Formatter: Automatic code formatting for consistent style
- Watch Mode: Automatic recompilation on file changes for rapid development
- Package Manager: Easy dependency management with
bpl install - Cross-Platform: Compile for Linux, macOS, Windows, ARM, and more
- VS Code Extension: Full language server with IntelliSense, go-to-definition, hover tooltips, and smart completions
- Incremental Compilation: Fast rebuilds with module caching
git clone https://github.com/pr0h0/bpl3.git
cd bpl3
./init.sh
bpl --versionYou'll need:
- Clang/LLVM (13+) - for compiling LLVM IR to native code
- Bun - for running the compiler
Linux (Ubuntu/Debian):
sudo apt-get install clang llvm
curl -fsSL https://bun.sh/install | bashmacOS:
brew install llvm
curl -fsSL https://bun.sh/install | bashWindows: Download LLVM from releases.llvm.org or use WSL.
bpl --version
echo 'extern printf(fmt: string, ...); frame main() ret int { printf("It works!\n"); return 0; }' > test.bpl
bpl test.bpl --runFor detailed installation instructions, see the Installation Guide.
Create hello.bpl:
extern printf(fmt: string, ...);
frame main() ret int {
printf("Hello, World!\n");
return 0;
}Compile and run:
bpl run hello.bplOr just compile:
bpl hello.bpl -o helloYou can execute snippets or piped input directly:
-
Evaluate a snippet from the command line:
bpl -e 'frame main() ret int { return 0; }' -
Compile from stdin (helpful with
cat/pipes):cat examples/hello-world/main.bpl | bpl --stdin
--emit tokens|ast|formatted|llvm works with both -e and --stdin; diagnostics show <eval>/<stdin> in locations.
Variables and Types:
extern printf(fmt: string, ...);
frame main() ret int {
local x: int = 42;
local name: string = "BPL";
local pi: float = 3.14159;
printf("%s: x = %d, pi = %f\n", name, x, pi);
return 0;
}Functions:
extern printf(fmt: string, ...);
frame add(a: int, b: int) ret int {
return a + b;
}
frame main() ret int {
local result: int = add(5, 3);
printf("5 + 3 = %d\n", result);
return 0;
}Structs and Methods:
extern printf(fmt: string, ...);
struct Point {
x: int,
y: int,
frame new(x: int, y: int) ret Point {
local p: Point;
p.x = x;
p.y = y;
return p;
}
frame print(this: Point) ret void {
printf("Point(%d, %d)\n", this.x, this.y);
}
}
frame main() ret int {
local p: Point = Point.new(10, 20);
p.print();
return 0;
}Generics:
extern printf(fmt: string, ...);
struct Box<T> {
value: T,
frame new(val: T) ret Box<T> {
local b: Box<T>;
b.value = val;
return b;
}
}
frame main() ret int {
local intBox: Box<int> = Box<int>.new(42);
local floatBox: Box<float> = Box<float>.new(3.14);
printf("Int: %d, Float: %f\n", intBox.value, floatBox.value);
return 0;
}Using Standard Library:
import [Vec] from "std/vec.bpl";
import [IO] from "std/io.bpl";
frame main() ret int {
local numbers: Vec<int> = Vec<int>.new(5);
numbers.push(10);
numbers.push(20);
numbers.push(30);
IO.log("Vector contents:");
local i: int = 0;
loop (i < numbers.len()) {
IO.printInt(numbers.get(i));
i = i + 1;
}
return 0;
}For more examples, check out the examples directory or the Quick Start Guide.
Comprehensive documentation is available in the docs/ directory:
- Introduction - What is BPL and why use it?
- Installation - Setup guide for all platforms
- Quick Start - Write your first program in 5 minutes
- Syntax and Comments - Basic syntax rules
- Types and Variables - Type system and declarations
- Operators - All operators explained
- Control Flow - If, loop, switch statements
- Functions - Declaring and calling functions
- Structs - Custom data types
- Generics - Generic programming
- Pointers - Memory manipulation
- Arrays and Tuples - Collections
- Inheritance - OOP in BPL
- Module System - Organizing code
- Error Handling - Exception handling
- Standard Library - Built-in functionality
- Language Specification - Formal specification
- CLI Reference - All command-line options
- Standard Library API - Complete API reference
# Compile and run a program
bpl run main.bpl
# Development mode with watch and auto-run
bpl dev main.bpl
# Build an executable
bpl build main.bpl -o myprogram
# Type check without code generation (fast)
bpl check main.bpl
# Create a new project
bpl new my-project
# Format code
bpl format main.bpl -w
# Clean build artifacts
bpl cleanCompile and execute a BPL program in one step:
# Run a program
bpl run main.bpl
# Pass arguments to the program
bpl run main.bpl arg1 arg2
# Run with optimization
bpl run main.bpl -O 2
# Run with timing statistics
bpl run main.bpl --timeDevelopment mode with automatic recompilation and execution:
# Watch and run on changes
bpl dev main.bpl
# Clear screen on each recompile
bpl dev main.bpl --clear
# Watch but only compile (don't run)
bpl dev main.bpl --no-runExplicitly compile a program:
# Basic compilation (generates LLVM IR)
bpl build main.bpl
# Specify output filename
bpl build main.bpl -o myprogram
# Verbose output
bpl build main.bpl -v
# Enable incremental compilation
bpl build main.bpl --cacheFast type checking without code generation:
# Check a single file
bpl check main.bpl
# Check multiple files
bpl check src/*.bpl
# JSON output for tooling
bpl check main.bpl --jsonCreate a new BPL project with standard structure:
# Create new project
bpl new my-project
cd my-project
bpl run main.bplThis creates:
bpl.json- Package manifestmain.bpl- Entry point with Hello Worldlib/- Local library directoryREADME.md- Project documentation.gitignore- Git ignore rules
Remove build artifacts:
# Remove all build artifacts
bpl clean
# Dry run (show what would be deleted)
bpl clean --dry-run
# Verbose output
bpl clean -vThese work with any command:
-v, --verbose Enable verbose output
-q, --quiet Suppress non-error output
-O <level> Optimization level: 0, 1, 2, or 3
--debug, -d Generate DWARF debug information
--time Show compilation time statistics
--cache Enable incremental compilation
--color/--no-color Force/disable colored output
--json Output in JSON format (for check command)Control what the compiler outputs:
# Emit LLVM IR (default)
bpl build main.bpl --emit llvm
# Emit AST as JSON
bpl build main.bpl --emit ast
# Emit tokens
bpl build main.bpl --emit tokens
# Format source code
bpl format main.bplCompile for different platforms and architectures:
# Cross-compile for ARM64 Linux
bpl build main.bpl --target aarch64-unknown-linux-gnu --march=armv8-a
# Cross-compile for Windows x64
bpl build main.bpl --target x86_64-pc-windows-gnu
# Cross-compile for macOS ARM64
bpl build main.bpl --target arm64-apple-darwin
# Specify sysroot for cross-compilation
bpl build main.bpl --target aarch64-unknown-linux-gnu --sysroot /opt/sysroots/aarch64
# Pass additional flags to clang
bpl build main.bpl --clang-flag=-O3 --clang-flag=-staticSupported target triples:
x86_64-pc-linux-gnu(Linux x64)aarch64-unknown-linux-gnu(Linux ARM64)arm64-apple-darwin(macOS ARM64)x86_64-apple-darwin(macOS x64)x86_64-pc-windows-gnu(Windows x64)
# Format and print to stdout
bpl format main.bpl
# Format and write back to file
bpl format -w main.bpl
# Format multiple files
bpl format -w src/**/*.bpl# Initialize a new project
bpl init my-project
# Create a package tarball
bpl pack
# Install a package
bpl install package-name-1.0.0.tgz
# Install all dependencies from bpl.json
bpl install
# List installed packages
bpl list
# Uninstall a package
bpl uninstall package-nameSee the Package Management Guide for details.
BPL provides command-line completion for Bash and Zsh shells:
# Generate Bash completion script
bpl completion bash > ~/.local/share/bash-completion/completions/bpl
# Or add to your ~/.bashrc:
source <(bpl completion bash)
# Generate Zsh completion script
mkdir -p ~/.local/share/zsh/completions
bpl completion zsh > ~/.local/share/zsh/completions/_bpl
# Add to ~/.zshrc:
fpath=(~/.local/share/zsh/completions $fpath)
# Reload completions
rm -f ~/.zcompdump; compinitAfter installation, you can use Tab to complete commands, flags, and file paths!
BPL features a rich, safe type system:
- Primitive types:
int,float,bool,char - Composite types: pointers, arrays, tuples
- User-defined types: structs with fields and methods
- Generics: Type parameters for functions and structs
- Type aliases: Create meaningful names for complex types
type UserID = int;
type Callback = Func<void>(int);
type Point3D = (float, float, float);
struct Result<T, E> {
ok: T,
err: E,
is_ok: bool
}Manual memory management with safety helpers:
extern malloc(size: i64) ret *void;
extern free(ptr: *void);
frame main() ret int {
# Allocate
local ptr: *int = cast<*int>(malloc(sizeof(int) * 10));
# Use
ptr[0] = 42;
# Free
free(cast<*void>(ptr));
return 0;
}Single and multiple inheritance supported:
struct Animal {
name: string,
frame speak() { printf("...\n"); }
}
struct Dog : Animal {
breed: string,
frame speak() { printf("Woof!\n"); } # Override
}
struct Bird : Animal {
wingspan: float
}
# Multiple inheritance
struct Platypus : Animal, Swimmer {
# ...
}Organize code across files:
# math.bpl
export add, multiply;
frame add(a: int, b: int) ret int {
return a + b;
}
frame multiply(a: int, b: int) ret int {
return a * b;
}# main.bpl
import add, multiply from "./math.bpl";
frame main() ret int {
local sum: int = add(5, 3);
local product: int = multiply(5, 3);
return 0;
}BPL includes a comprehensive standard library:
| Module | Description | Example |
|---|---|---|
std/io.bpl |
Input/output operations | IO.log("Hello") |
std/string.bpl |
String manipulation | String.concat(a, b) |
std/array.bpl |
Dynamic arrays | Array<int>.new(10) |
std/vec.bpl |
Growable vectors | Vec<int>.new(0) |
std/map.bpl |
Hash maps | Map<K, V>.new() |
std/set.bpl |
Hash sets | Set<T>.new() |
std/fs.bpl |
File system ops | FS.readFile(path) |
std/math.bpl |
Math functions | Math.sqrt(x) |
std/time.bpl |
Time operations | Time.now() |
std/json.bpl |
JSON parsing | JSON.parse(str) |
std/option.bpl |
Optional values | Option<T>.some(val) |
std/result.bpl |
Error handling | Result<T, E> |
See the Standard Library documentation for complete API reference.
bpl3/
βββ compiler/ # Compiler implementation
β βββ frontend/ # Lexer (Peggy) and parser
β βββ middleend/ # Type checker, module resolver, linker
β βββ backend/ # LLVM IR code generation
β β βββ codegen/ # Generators for expressions, types, etc.
β βββ formatter/ # Code formatter
β βββ linter/ # Code linting
β βββ docs/ # Documentation generator
β βββ common/ # Shared utilities
β βββ AST.ts # AST definitions
β βββ CompilerError.ts # Error handling
β βββ Config.ts # Centralized configuration
β βββ Logger.ts # Structured logging
β βββ ... # Path resolution, source management
βββ cli/ # Command-line interface
β βββ index.ts # CLI entry point
β βββ commands/ # Subcommand handlers
β βββ completions/ # Shell completions
βββ docs/ # Comprehensive documentation
β βββ 01-introduction.md
β βββ 02-installation.md
β βββ 03-quick-start.md
β βββ ... # 50+ documentation files
βββ examples/ # 70+ working examples
β βββ hello-world/
β βββ fibonacci/
β βββ generics/
β βββ stdlib_*/ # Standard library examples
β βββ ...
βββ grammar/ # PEG grammar definitions
β βββ bpl.peggy # Language grammar
βββ lib/ # Standard library
β βββ io.bpl # Input/output
β βββ array.bpl # Dynamic arrays
β βββ vec.bpl # Vectors
β βββ map.bpl # Hash maps
β βββ string.bpl # String utilities
β βββ ... # 20+ stdlib modules
βββ tests/ # Comprehensive test suite
β βββ Integration.test.ts
β βββ Parser.test.ts
β βββ ...
βββ benchmark/ # Performance benchmarks
βββ vscode-ext/ # VS Code extension
βββ playground/ # Web playground (optional)
βββ index.ts # Main entry point
βββ LANGUAGE_SPEC.md # Language specification
βββ README.md # This file
The examples/ directory contains 70+ working examples demonstrating every language feature:
hello-world/- Your first programvariables/- Variable declarationsmath/- Arithmetic operationsif-statements/- Conditionalsloops/- Loop constructs
functions/- Function definitionsstructs/- Custom data typesarrays/- Array operationspointers/- Pointer manipulationstrings/- String handling
generics/- Generic programminggenerics_advanced/- Complex genericsobjects_inheritance/- OOP patternsmulti_inheritance/- Multiple inheritanceerror_handling/- Exception handling
stdlib_io/- I/O operationsstdlib_vec/- Dynamic arraysstdlib_map_set/- Hash maps and setsstdlib_json/- JSON parsingstdlib_fs/- File systemstdlib_time/- Time operations
fibonacci/- Fibonacci sequencecollatz/- Collatz conjecturerecursive_algorithms/- Recursion examples
Each example includes:
- Source code (
.bplfiles) - Expected output (in test configurations)
- Build and test scripts
Run any example:
cd examples/fibonacci
bpl main.bpl --run# Run all tests
bun test
# Run specific test file
bun test tests/Integration.test.ts
# Run tests matching pattern
bun test -t "generics"# Check TypeScript types
bun run check# Build executable
bun run build
# Development mode (no build)
bun index.ts examples/hello-world/main.bpl --runContributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
bun test) - Format code (
bun run format) - Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing-feature) - Open a Pull Request
See CONTRIBUTING.md for detailed guidelines.
- Start with the Quick Start Guide
- Read the Language Specification
- Explore example programs
- Check the Standard Library docs
Coming soon!
- GitHub Discussions - Ask questions, share projects
- GitHub Issues - Report bugs, request features
- Discord - Real-time chat (link coming soon)
BPL is under active development. The compiler is stable with 1,342 tests passing across 88 test files.
Build Status:
- β 1,342 tests passing (100%)
- β 0 ESLint errors/warnings
- β 0 TypeScript errors
- β 100+ working examples
- Full LLVM IR backend
- Static type system with generics
- Structs with inheritance
- Module system with imports/exports
- Exception handling (try/catch)
- Package manager
- Code formatter
- Cross-compilation support
- Standard library (20+ modules)
- VS Code extension
- Comprehensive test suite (1,342 tests)
- Documentation (50+ pages)
- Enum types with pattern matching
- String interpolation
- Lambda expressions
- Tuple destructuring (including nested)
- Operator overloading (24 operators)
- Intrinsics (math, bit manipulation, memory)
- IDE integrations (beyond VS Code)
- More stdlib modules (networking, threads)
- Optimization passes
- Package registry
- Incremental compilation improvements
- Inline assembly improvements
- C++ interop improvements
- WebAssembly target
- Self-hosting compiler
See TODO.md for detailed task list.
BPL produces competitive performance with C/C++:
| Benchmark | BPL | C (gcc -O2) | C++ (g++ -O2) |
|---|---|---|---|
| Fibonacci (recursive) | 1.23s | 1.19s | 1.21s |
| Array sum | 0.45s | 0.43s | 0.44s |
| Matrix multiply | 2.10s | 2.05s | 2.08s |
Note: Benchmarks run on AMD Ryzen 9 5900X, Linux 5.15
| Feature | BPL | C | C++ | Rust | Go |
|---|---|---|---|---|---|
| Manual memory mgmt | β | β | β | β * | β |
| Generics | β | β | β | β | β |
| Inheritance | β | β | β | β | β |
| Exceptions | β | β | β | β | β |
| Module system | β | β | β | β | |
| Package manager | β | β | β | β | |
| Memory safety** | β | β | β | β | |
| Learning curve | ββ | ββ | βββββ | ββββ | ββ |
| Compile speed | β‘β‘ | β‘β‘β‘ | β‘ | β‘ | β‘β‘β‘ |
| Runtime performance | β‘β‘β‘ | β‘β‘β‘ | β‘β‘β‘ | β‘β‘β‘ | β‘β‘ |
*Rust uses ownership/borrowing instead of GC
**Planned for BPL
BPL is licensed under the Apache License 2.0.
See LICENSE for details.
pr0h0
- GitHub: @pr0h0
- Email: contact via GitHub
- LLVM Project - For the amazing compiler infrastructure
- Bun - For the fast JavaScript runtime
- Community Contributors - For bug reports and feature requests
Need help?
- Documentation - Check the docs/ directory
- Examples - Browse examples/
- Issues - Search or create a GitHub Issue
- Discussions - Join GitHub Discussions
- GitHub Repository: https://github.com/pr0h0/bpl3
- Documentation: docs/
- Examples: examples/
- Language Spec: LANGUAGE_SPEC.md
Happy Coding! π
BPL - Where performance meets modern language design