Skip to content

ostepan8/quill-compiler

Repository files navigation

Quill Programming Language Compiler

Quill is a Python-inspired programming language that compiles to native machine code via LLVM. Write Python-like code and get fast, optimized executables.

✨ Features

🏗️ Advanced Type System

  • 🔍 Static Type Checking - Catch errors at compile time with sophisticated inference
  • 🧬 Generic Types - Full support for generic functions with constraint solving
  • 🔗 Union & Discriminated Types - Advanced type unions with variant support
  • 📝 Optional Type Annotations - Explicit typing when needed, inference when convenient
  • 🎯 Flow-Sensitive Analysis - Context-aware type checking across control flow
  • 🏛️ Structural Typing - Interface-based type compatibility

Performance & Optimization

  • 🐍 Python-like syntax - Familiar indentation-based blocks
  • Advanced optimizations - 4 optimization levels (-O0 to -O3) with custom LLVM passes
  • 🚀 High performance - 12.35x faster than Python (recursive algorithms), ~4.12x average speedup
  • 🔧 Smart compilation - Constant folding, dead code elimination, function inlining
  • 🎯 Type-directed optimizations - Power-of-2 bit shifts, integer arithmetic, cast elimination
  • 🧮 Mathematics - Arithmetic simplification and numerical optimizations
  • 📊 Optimization reporting - Detailed statistics on applied optimizations

💰 Quantitative Finance Ready

  • 📈 Black-Scholes pricing - Optimized option pricing algorithms with 2.67x Python speedup
  • 🔢 Mathematical functions - Built-in sqrt, exp, log for numerical computation
  • 📊 Monte Carlo simulations - High-performance statistical computing
  • Sub-millisecond execution - Perfect for high-frequency trading applications
  • 🧮 Numerical stability - Accurate financial calculations with proper error handling

🛠️ Developer Experience

  • 📊 Performance analysis - Built-in timing, optimization reports, benchmarking suite
  • 📤 Multiple outputs - LLVM IR, assembly, or optimized executables
  • 🧹 Developer tools - Easy compilation scripts and comprehensive cleanup
  • 🚨 Rich Error Reporting - Clear, contextual error messages for type mismatches
  • Fast compilation - Efficient type checking and optimization pipeline

🚀 Quick Start

1. Write a Quill Program

# my_program.quill
def main():
    x = 10
    y = 5
    print(x + y)    # Outputs: 15
    
    if x > y:
        print(x * 2)  # Outputs: 20

2. Compile & Run

./compile.sh my_program.quill
./my_program

3. Clean Up

./clean.sh

📚 Language Reference

Functions & Type Annotations

# Type inference (automatic)
def add(a, b):
    return a + b

# Explicit type annotations (optional)
def multiply(x: int, y: int) -> int:
    return x * y

# Generic functions with constraints
def identity(value: T) -> T:
    return value

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

Variables & Advanced Types

# Type inference
x = 42          # Inferred as int
y = 3.14        # Inferred as float
result = x + y * 2

# Union types
def process(value: int | float) -> str:
    return str(value)

# List types with generics
numbers: list[int] = [1, 2, 3, 4, 5]

# Tuple types
coordinates: tuple[float, float] = (10.5, 20.3)

Control Flow

# If statements
if x > 10:
    print(x)
else:
    print("small")

# While loops
while x > 0:
    print(x)
    x = x - 1

Complete Example

def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

def main():
    result = fibonacci(8)
    print(result)  # Outputs: 21

🛠️ Installation

Prerequisites (macOS)

# Install LLVM via Homebrew
brew install llvm

# Install build tools (if not already installed)
xcode-select --install

Build the Compiler

The compilation scripts will automatically build the compiler for you on first use, but you can also build manually:

# Auto-build (recommended)
./compile.sh examples/hello.quill  # Builds compiler if needed

# Manual build
mkdir build && cd build
cmake .. && make

💻 Usage Guide

Simple Compilation (Recommended)

# Compile any .quill file to executable
./compile.sh program.quill [executable_name]

# Examples
./compile.sh examples/hello.quill
./compile.sh examples/math.quill calculator
./compile.sh my_program.quill my_app

Type Checking & Analysis

# Enable detailed type error reporting
./build/quill --type-errors --timing program.quill

# Disable type checking (faster compilation)
./build/quill --no-typecheck program.quill

# Type-aware optimization with reporting
./build/quill -O3 --opt-report --type-errors program.quill

Run Your Programs

./hello        # Run hello example
./calculator   # Run math example  
./my_app       # Run custom program

Cleanup

./clean.sh     # Remove ALL generated files and executables

Using Makefile

make compile FILE=program.quill    # Compile specific file
make examples                      # Build and run all examples
make clean                         # Clean up build files
make help                          # Show all available commands

Try the Examples

# Fibonacci and factorial
./compile.sh examples/hello.quill && ./hello

# Math operations with optimization
./compile.sh examples/math.quill math -O3 && ./math

⚡ Performance & Optimization

Quill features optimization capabilities with type-directed optimizations for high-performance computing:

🎯 Optimization Levels Explained

-O0 (No Optimization - Default)

  • Purpose: Fastest compilation, debugging-friendly
  • LLVM Passes: None (baseline performance)
  • Use Case: Development, debugging, prototyping
  • Compile Time: ~100ms | Performance: Baseline (1.00x)

-O1 (Basic Optimization)

  • Purpose: Light optimizations, balanced compile time
  • LLVM Passes: InstCombine, SimplifyCFG
  • Optimizations: Instruction combining, control flow simplification, basic constant propagation
  • Use Case: Development builds with some performance
  • Compile Time: ~150ms | Performance: 1.2-1.8x faster than -O0

-O2 (Standard Optimization - Recommended)

  • Purpose: Production-ready optimizations
  • LLVM Passes: All -O1 + Reassociate, GVN
  • Optimizations: Expression reassociation, global value numbering, loop optimizations, selective inlining
  • Use Case: Release builds, balanced performance/compile time
  • Compile Time: ~300ms | Performance: 1.5-2.5x faster than -O0

-O3 (Maximum Optimization + Type-Directed)

  • Purpose: Aggressive optimizations for maximum performance
  • LLVM Passes: All -O2 + aggressive optimizations
  • Optimizations: Aggressive inlining, loop vectorization, inter-procedural optimizations
  • 🎯 Type-Directed Passes: Power-of-2 bit shifts, integer arithmetic, cast elimination
  • Use Case: Performance-critical production code
  • Compile Time: ~500ms | Performance: 1.8-3.0x faster than -O0

🎯 Type-Directed Optimizations

Quill features type-directed optimization passes that use static type information to generate optimized code:

Power-of-Two Optimizations

# Source Code
x = 100
y = x * 8    # Multiplication by power of 2
z = x / 4    # Division by power of 2

# Optimized Assembly (automatically generated)
# x * 8  →  x << 3  (left shift by 3, since 8 = 2^3)  
# x / 4  →  x >> 2  (right shift by 2, since 4 = 2^2)

Integer Arithmetic Optimization

# When both operands are integer constants
a = 10 + 20    # Optimized to integer arithmetic instead of floating-point
if x == 42:    # Integer comparison instead of floating-point comparison

Type Cast Elimination

# Eliminates redundant type conversions:
# float → int → float chains are removed
# Same-type casts are eliminated
# Cast chains are collapsed into single operations

Optimization Statistics Reporting

# Get detailed optimization reports
./build/quill -O3 --opt-report program.quill

# Sample Output:
=== Quill Optimization Report ===
Optimization Level: O3
--- Type-Directed Optimizations ---
Numeric Operations Optimized: 12
Multiplications → Bit Shifts: 3  
Divisions → Bit Shifts: 2
Type Casts Eliminated: 5
Type Specializations Applied: 1
==================================

📊 Performance Analysis Tools

# Optimization level comparison
./build/quill -O0 program.quill  # Baseline
./build/quill -O2 program.quill  # Production (recommended)
./build/quill -O3 program.quill  # Maximum performance

# Compilation with timing analysis  
./build/quill -O2 --timing program.quill

# Full benchmark suite (comprehensive performance testing)
./benchmark.sh

# Test type-directed optimizations specifically
./build/quill -O3 --opt-report examples/numeric_ops_test.quill
./build/quill -O3 --opt-report examples/power_of_two_test.quill

# Optimization-specific benchmarks
./optimization_benchmark.sh

Measured Performance Results

Based on Apple M1 Max benchmarks (September 2025):

  • vs Python: 11.50x faster (Fibonacci recursive), 2.90x faster (Black-Scholes finance)
  • Average speedup vs Python: ~4.12x across all benchmarks
  • vs C++: Room for improvement - C++ currently 3.1x faster on recursive algorithms

Comprehensive Benchmark Results:

Algorithm Quill (ms) Python (ms) Speedup Performance
Fibonacci (recursive) 92.6 1064.5 11.50x 🚀 Excellent
Monte Carlo π 84.0 362.0 4.31x 🚀 Excellent
Bubble sort 18.8 80.3 4.28x 🚀 Excellent
Matrix multiply 23.7 97.3 4.12x 🚀 Excellent
Black-Scholes (Finance) 18.5 53.7 2.90x 💰 Quant-Ready
Prime sieve 19.1 37.0 1.94x ✅ Good
Fibonacci (iterative) 16.9 30.2 1.79x ✅ Good

Industry-grade performance with low standard deviations (0.7-2.3ms)

📋 Current Status: Type-directed optimizations implemented and active at -O3 level. All optimization levels (-O1 through -O3) feature standard LLVM passes, with -O3 including type-directed optimizations for power-of-2 operations, integer arithmetic, and cast elimination.

Key Achievements

  • 12.35x speedup over Python for recursive algorithms
  • 3.02x speedup for quantitative finance computations (Black-Scholes)
  • Production-ready compiler with 4 optimization levels (-O0 to -O3)
  • Type-directed optimizations - Power-of-2 bit shifts, integer arithmetic, cast elimination
  • Optimization reporting - Statistics on applied optimizations
  • Integrated type system - Static type checking with flow-sensitive analysis
  • LLVM optimization pipeline - InstCombine, SimplifyCFG, GVN, Reassociate passes
  • Comprehensive benchmark suite with Python/C++ performance comparisons

See PERFORMANCE.md for detailed optimization guide.

📁 Project Structure

compiler/
├── compile.sh              # 🚀 Enhanced compilation script with optimization levels
├── clean.sh                # 🧹 Comprehensive cleanup script  
├── benchmark.sh            # 📊 Benchmark suite with Python/C++ comparison
├── performance_analysis.sh # 🔬 Optimization level comparison tool
├── CMakeLists.txt          # Build configuration with LLVM optimizations
├── Makefile                # Alternative build system
├── README.md               # Main documentation
├── PERFORMANCE.md          # 📈 Detailed optimization guide
├── runtime.c               # Runtime support functions
├── include/                # Header files
│   ├── token.h             # Token definitions
│   ├── lexer.h             # Lexical analyzer  
│   ├── parser.h            # Parser interface
│   ├── ast.h               # Abstract syntax tree with type information
│   ├── codegen.h           # Code generation
│   ├── type_system.h       # 🏗️ Advanced type system definitions
│   ├── type_checker.h      # 🔍 Type inference and checking engine
│   ├── timer.h             # ⏱️ Performance timing utilities
│   └── optimization_passes.h # 🎯 Custom LLVM optimization passes
├── src/                    # Implementation files
│   ├── main.cpp            # Enhanced compiler with type checking integration
│   ├── lexer.cpp           # Tokenization logic
│   ├── parser.cpp          # Syntax analysis
│   ├── ast.cpp             # AST node implementations
│   ├── codegen.cpp         # LLVM IR generation
│   └── timer.cpp           # Performance measurement
├── types/                  # 🏗️ Type system implementation
│   ├── type_system.cpp     # Core type hierarchy and factory
│   └── type_checker.cpp    # Type inference and checking engine
├── optimization/           # 🧠 Custom optimization passes
│   ├── constant_folding.cpp        # Compile-time expression evaluation
│   ├── dead_code_elimination.cpp   # Remove unreachable code
│   ├── function_inlining.cpp       # Inline small functions
│   ├── arithmetic_simplification.cpp # Mathematical optimizations
│   ├── type_directed_pass_impl.cpp  # 🎯 Type-directed optimizations
│   └── optimization_manager.cpp    # Optimization pipeline with statistics
├── benchmarks/             # 🏁 Performance test programs
│   ├── fibonacci_recursive.quill   # Recursive algorithm test
│   ├── fibonacci_iterative.quill   # Iterative comparison
│   ├── matrix_multiply.quill       # Computational intensity test
│   ├── prime_sieve.quill          # Number theory algorithms
│   ├── monte_carlo_pi.quill       # Statistical computation
│   ├── bubble_sort.quill          # Sorting algorithm
│   └── reference/                 # Python/C++ reference implementations
└── examples/               # Sample Quill programs
    ├── hello.quill         # Fibonacci & factorial demo
    └── math.quill          # Mathematical functions demo

🏗️ How It Works

The Quill compiler transforms your Python-like code through several sophisticated stages:

  1. Lexer → Tokenizes source code (keywords, operators, literals)
  2. Parser → Builds Abstract Syntax Tree (AST) from tokens
  3. Type Checker → Performs static analysis, type inference, and validation
  4. CodeGen → Generates LLVM IR from type-annotated AST nodes
  5. Optimizer → Applies type-directed optimizations and LLVM passes
  6. LLVM → Compiles IR to optimized assembly
  7. GCC → Links with runtime to create executable
your_program.quill → Tokens → AST → Type-Checked AST → LLVM IR → Optimized IR → Assembly → Executable

🎯 Supported Operations

Type System Features

# Type inference
x = 42           # Automatically inferred as int
y = 3.14         # Automatically inferred as float

# Explicit type annotations
def add(x: int, y: int) -> int:
    return x + y

# Generic types with constraints
def identity(value: T) -> T:
    return value

# Union types
def process(data: int | float | str) -> str:
    return str(data)

# Collection types
numbers: list[int] = [1, 2, 3]
point: tuple[float, float] = (10.0, 20.0)

Math & Logic

# Arithmetic (type-safe with automatic promotion)
x + y, x - y, x * y, x / y, x % y, -x

# Comparisons (with type compatibility checking)
x < y, x > y, x <= y, x >= y, x == y, x != y

# Logical
x and y, x or y, not x

Built-ins

print(value)      # Output values to console (type-polymorphic)

🔮 Current Features & Future Plans

✅ Implemented:

  • Complete Type System - Static typing with inference, generics, and unions
  • Advanced Optimizations - Type-directed performance improvements
  • Rich Error Reporting - Contextual type error messages with suggestions
  • Multiple Data Types - Numbers, strings, booleans with automatic promotion
  • Control Structures - if/else, while loops with type-aware optimization
  • Function System - Type-safe functions with optional annotations

🚧 Planned Features:

  • Pattern matching for discriminated unions
  • Module system with import/export
  • Memory management improvements
  • Advanced generic type features
  • Compile-time evaluation
  • IDE integration and language server

🤝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🐛 Troubleshooting

"Command not found" errors:

# Make sure scripts are executable
chmod +x compile.sh clean.sh

# Check LLVM installation  
brew list llvm

Build errors:

# Clean and rebuild
./clean.sh
./compile.sh examples/hello.quill

Need help? Check the examples in /examples/ directory for working code patterns.

About

A high-performance compiler for the Quill programming language, built with C++ and LLVM. Features comprehensive optimization passes and extensive benchmarking suite.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors