Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PIE Programming Language

A compiled, statically-typed language with C-like syntax built on LLVM

Quick StartDocumentationExamplesFeatures


Overview

PIE is a statically-typed, compiled programming language with C-like syntax and modern high-level features. It compiles to native machine code via LLVM, offering solid performance while providing built-in support for arrays, dictionaries, regular expressions, HTTP, JSON, file I/O, and more.

Key Features

  • LLVM-Based Compilation — Fast native code via LLVM IR
  • C-Like Syntax — Familiar structure for C/C++ programmers
  • Static Typing — Type errors caught at compile time
  • Module System — Import standard library and user-defined modules
  • Rich Standard Library — Math, strings, file I/O, regex, HTTP, JSON, SQLite, and more
  • Dynamic Arrays — Growable arrays with built-in operations
  • Dictionaries — Hash maps with automatic type inference
  • Regular Expressions — NFA-based Kleene syntax pattern matching
  • TCP Sockets — Raw network socket support
  • HTTP Client & Server — Full HTTP support via libcurl and libmicrohttpd

Quick Start

Prerequisites

  • Python 3.7+
  • LLVM tools: llc, clang
  • Python packages: llvmlite >= 0.45.1, ply >= 3.11
  • System libraries (for HTTP/JSON modules): libcurl, libmicrohttpd, libjansson, libsqlite3

Installation

# Clone the repository
git clone https://github.com/Pie-Compiler/PIE-Compiler-V1-Python.git
cd PIE-Compiler-V1-Python

# Set up virtual environment
python3 -m venv venv
source venv/bin/activate

# Install Python dependencies
pip install llvmlite ply

# Install system libraries (Ubuntu/Debian)
sudo apt-get install -y libcurl4-openssl-dev libmicrohttpd-dev libjansson-dev libsqlite3-dev

Your First PIE Program

Create hello.pie:

// Hello, World in PIE
output("Hello, PIE!", string);

int x = 10;
int y = 20;
output("Sum: " + (x + y), string);

Compile and run:

python3 src/main.py hello.pie
./program

Output:

Hello, PIE!
Sum: 30

Documentation

Full documentation is in the docs/ directory:

File Description
language-reference.md Complete syntax, types, operators, control flow
standard-library.md All built-in functions
module-system.md Creating and importing modules
advanced-features.md Arrays, dicts, regex, networking
examples.md Practical examples and tutorials
quick-reference.md Syntax cheat sheet

Language Overview

Data Types

int    count = 42;           // 32-bit signed integer
float  pi    = 3.14159;      // 64-bit double-precision float
char   grade = 'A';          // Single ASCII character
string name  = "Alice";      // Null-terminated string
bool   valid = true;         // Boolean (true / false)
dict   info  = {};           // Hash map (string keys, mixed values)
regex  pat   = regex_compile("a+"); // Compiled regex pattern
file   f     = file_open("x.txt", "r"); // File handle
socket sock  = tcp_socket(); // TCP socket

Variables and Output

int age = 25;
string city = "Nairobi";

output(age, int);               // Prints: 25
output(city, string);           // Prints: Nairobi

// String concatenation with + embeds values inline
output("Age: " + age, string);          // Age: 25
output("City: " + city, string);        // City: Nairobi

// Float output with precision
float score = 95.5677;
output(score, float);           // 95.57 (2 decimal default)
output(score, float, 4);        // 95.5677

Control Flow

// If / else if / else
if (x > 10) {
    output("big", string);
} else if (x == 10) {
    output("ten", string);
} else {
    output("small", string);
}

// For loop
for (int i = 0; i < 5; i++) {
    output(i, int);
}

// While loop
while (x > 0) {
    x--;
}

// Do-while loop
do {
    output(x, int);
    x++;
} while (x < 5);

// Switch
switch (day) {
    case 1:
        output("Monday", string);
        break;
    case 2:
        output("Tuesday", string);
        break;
    default:
        output("Other", string);
}

Functions

// Integer function
int add(int a, int b) {
    return a + b;
}

// Recursive function
int factorial(int n) {
    if (n <= 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

// String-returning function
string grade(float score) {
    if (score >= 90.0) { return "A"; }
    if (score >= 80.0) { return "B"; }
    return "C";
}

// Void function (entry point)
void main() {
    output(add(3, 4), int);           // 7
    output(factorial(5), int);        // 120
    output(grade(85.0), string);      // B
}

Note: PIE supports both top-level statements (no main function needed for simple scripts) and main() as the entry point.

Arrays

// Static arrays (fixed size)
int nums[5] = [1, 2, 3, 4, 5];
output(nums[0], int);           // 1

// Dynamic arrays (growable)
string names[] = ["Alice", "Bob", "Charlie"];

arr_push(names, "David");       // Add element
output(arr_size(names), int);   // 4

string last = arr_pop(names);   // Remove and return last
output(last, string);           // David

// Array utilities
int exists = arr_contains(names, "Bob");  // 1 (true)
int idx    = arr_indexof(names, "Bob");   // 1
float avg  = arr_avg([10, 20, 30]);       // 20.0

// Print entire array
output(names, array);

Multi-dimensional (static):

int matrix[3][3];
matrix[0][0] = 1;
output(matrix[0][0], int);

Dictionaries

dict student = {
    "name": "Alice",
    "age":  20,
    "GPA":  3.8
};

// Type is inferred from the receiving variable
string name = dict_get(student, "name");  // infers string
int    age  = dict_get(student, "age");   // infers int
float  gpa  = dict_get(student, "GPA");   // infers float

output("Name: " + name + ", Age: " + age, string);

// Add / update keys
dict_set(student, "age", 21);
dict_set(student, "year", 2);

// Check / delete
int has = dict_has_key(student, "year");  // 1
dict_delete(student, "year");

// Missing keys return type defaults: "" for string, 0 for int, 0.0 for float
string missing = dict_get(student, "absent");  // ""

Modules

Import standard library modules:

import http;
import json;
import sqlite;
import date;

// HTTP GET
string resp = http.get("https://jsonplaceholder.typicode.com/todos/1");
output(resp, string);

Import user-defined modules:

// mathutils.pie defines: export int square(int x) { return x * x; }
import mathutils;

output(mathutils.square(5), int);   // 25

Import from a subdirectory:

import util from "./Utils/";
output(util.add(3, 4), int);        // 7

Examples

String Manipulation

string text = "  Hello, PIE World!  ";

string trimmed  = string_trim(text);
string upper    = string_to_upper(trimmed);
string reversed = string_reverse("HELLO");

output(trimmed,  string);   // Hello, PIE World!
output(upper,    string);   // HELLO, PIE WORLD!
output(reversed, string);   // OLLEH

int pos = string_index_of(trimmed, "PIE");
output("PIE at index: " + pos, string);  // PIE at index: 7

File I/O

// Write a file
file f = file_open("notes.txt", "w");
if (f != null) {
    int count = 42;
    file_write(f, "Count: " + count + "\n");
    file_write(f, "Done!\n");
    file_close(f);
}

// Read all content
file r = file_open("notes.txt", "r");
if (r != null) {
    string content = file_read_all(r);
    output(content, string);
    file_close(r);
}

// Read line by line into array
file g = file_open("notes.txt", "r");
if (g != null) {
    string lines[] = file_read_lines(g);
    for (int i = 0; i < arr_size(lines); i++) {
        output("Line " + (i+1) + ": " + lines[i], string);
    }
    file_close(g);
}

Regular Expressions

PIE uses Kleene syntax with . for concatenation and | for alternation:

regex vowels = regex_compile("(a|e|i|o|u)+");
output(regex_match(vowels, "aeiou"), int);  // 1 (match)
output(regex_match(vowels, "xyz"),   int);  // 0 (no match)
regex_free(vowels);

// Phone number pattern: exactly 10 digits
string digits = "(0|1|2|3|4|5|6|7|8|9)";
regex phone = regex_compile("(" + digits + "." + digits + "." + digits + "):10");
output(regex_match(phone, "0712345678"), int);  // 1
regex_free(phone);

HTTP Client

import http;

string resp = http.get("https://jsonplaceholder.typicode.com/todos/1");
int code = http.get_status_code();

output("Status: " + code, string);
output(resp, string);

JSON Processing

import json;

// Build a JSON object
json.object user = json.create_object();
json.set_string(user, "name", "Bob");
json.set_int(user, "age", 28);

string serialized = json.stringify(user);
output(serialized, string);  // {"name":"Bob","age":28}

// Parse JSON
json.object parsed = json.parse("{\"x\": 10, \"y\": 20}");
int x = json.get_int(parsed, "x");
output("x = " + x, string);  // x = 10

SQLite Database

import sqlite;

database db = sqlite.open("app.sqlite");

sqlite.exec(db, "CREATE TABLE IF NOT EXISTS items (id INTEGER PRIMARY KEY, name TEXT)");
sqlite.exec(db, "INSERT INTO items (name) VALUES ('Widget')");

dict rows[] = sqlite.query(db, "SELECT * FROM items");
for (int i = 0; i < arr_size(rows); i++) {
    dict row = rows[i];
    string n = dict_get_string(row, "name");
    output("Item: " + n, string);
}

sqlite.close(db);

HTTP Server

import http;

void handler(ptr request, ptr response) {
    string method = http.request_get_method(request);
    string path   = http.request_get_path(request);

    if (method == "GET" && path == "/") {
        http.response_set_status(response, 200);
        http.response_set_header(response, "Content-Type", "text/plain");
        http.response_set_body(response, "Hello from PIE!");
    } else {
        http.response_set_status(response, 404);
        http.response_set_body(response, "Not Found");
    }
}

void main() {
    output("Server running on port 8080", string);
    http.listen(8080, handler);
}

Standard Library Reference

Math

Function Signature Description
sqrt float(float) Square root
pow float(float, float) Power
abs float(float) Absolute value
abs_int int(int) Integer absolute value
floor, ceil, round float(float) Rounding
min, max float(float, float) Min/max (float)
min_int, max_int int(int, int) Min/max (int)
sin, cos, tan float(float) Trigonometry
log, log10, exp float(float) Logarithm/exp
rand int() Random integer
rand_range int(int, int) Random in range
srand void(int) Seed random
pi, e float() Math constants

Strings

Function Description
strlen(s) Length
strcmp(a, b) Compare (0 if equal)
strcat(dest, src) Concatenate
string_to_upper(s) Uppercase
string_to_lower(s) Lowercase
string_trim(s) Strip whitespace
string_substring(s, start, len) Extract substring
string_index_of(haystack, needle) Find position (-1 if not found)
string_replace_char(s, old, new) Replace character
string_reverse(s) Reverse
string_count_char(s, ch) Count occurrences
string_char_at(s, i) Character at index

Type Conversions

int   n = string_to_int("42");       // "42" → 42
float f = string_to_float("3.14");   // "3.14" → 3.14
char  c = string_to_char("Hello");   // "Hello" → 'H'
int   a = char_to_int('A');          // 'A' → 65
char  h = int_to_char(72);           // 72 → 'H'
float g = int_to_float(7);           // 7 → 7.0
int   i = float_to_int(3.9);         // 3.9 → 3 (truncates)

Array Functions

Function Description
arr_push(arr, val) Append element
arr_pop(arr) Remove and return last element
arr_size(arr) Number of elements
arr_contains(arr, val) Returns 1 if val exists
arr_indexof(arr, val) Index of val (-1 if not found)
arr_avg(arr) Average of numeric array

Dictionary Functions

Function Description
dict_get(d, key) Get value (type inferred from context)
dict_set(d, key, val) Set value
dict_has_key(d, key) Returns 1 if key exists
dict_key_exists(d, key) Alias for dict_has_key
dict_delete(d, key) Remove key
dict_get_int(d, key) Get int value explicitly
dict_get_float(d, key) Get float value explicitly
dict_get_string(d, key) Get string value explicitly

Time Functions

int ts = time_now();                  // Unix timestamp
string local = time_to_local(ts);     // "HH:MM:SS" local time

Cryptography (Educational)

string enc = caesar_cipher("HELLO", 3);    // "KHOOR"
string dec = caesar_decipher("KHOOR", 3);  // "HELLO"
string r13 = rot13("SECRET");              // "FRPERG"
string xor = xor_cipher("text", "key");    // XOR encryption

Operators

Category Operators
Arithmetic + - * / %
Comparison == != < > <= >=
Logical && || !
Assignment =
Increment ++ -- (prefix and postfix)
String concat + (also converts ints/floats)

String comparison works with > and < using string length:

// Compares string lengths
if ("hello" > 3) {
    output("long string", string);
}

Comments

// Single-line comment

/*
   Multi-line
   comment
*/

Project Structure

PIE-Compiler-V1-Python/
├── src/
│   ├── main.py                  # Compiler entry point
│   ├── frontend/
│   │   ├── lexer.py             # NFA/DFA tokenizer (Thompson's construction)
│   │   ├── parser.py            # PLY LALR(1) parser
│   │   ├── ast.py               # AST node definitions
│   │   ├── semanticAnalysis.py  # Type checking and validation
│   │   └── symbol_table.py      # Symbol management
│   ├── backend/
│   │   └── llvm_generator.py    # LLVM IR code generation
│   └── runtime/                 # C runtime library
│       ├── runtime.c            # I/O (input/output)
│       ├── math_lib.c           # Math functions
│       ├── string_lib.c         # String utilities
│       ├── d_array.c            # Dynamic arrays
│       ├── dict_lib.c           # Dictionaries
│       ├── regex_lib.c          # NFA-based regex engine
│       ├── file_lib.c           # File I/O
│       ├── net_lib.c            # TCP sockets
│       ├── time_lib.c           # Time functions
│       ├── crypto_lib.c         # Caesar cipher, ROT13, XOR
│       ├── pie_http.c/h         # HTTP client/server (libcurl + libmicrohttpd)
│       ├── pie_json.c/h         # JSON (jansson)
│       ├── pie_sqlite.c/h       # SQLite
│       └── pie_date.c/h         # Date/time module
├── stdlib/                      # Standard library modules
│   ├── http/                    # HTTP module
│   ├── json/                    # JSON module
│   ├── date/                    # Date/time module
│   └── sqlite/                  # SQLite module
├── testFiles/                   # Example/test programs
│   ├── DataTypes.pie
│   ├── Arrays.pie
│   ├── Dictionaries.pie
│   ├── Functions.pie
│   ├── Recursion.pie
│   ├── NestedFunctions.pie
│   ├── File_I_O.pie
│   ├── DataManipulation.pie
│   ├── Regex.pie
│   ├── Database.pie
│   ├── Network.pie
│   ├── HttpClient.pie
│   ├── HttpServer.pie
│   ├── Json.pie
│   └── Modular.pie
├── examples/
│   ├── modules/                 # Standard module examples
│   └── user_modules/            # User-defined module examples
├── docs/                        # Documentation
└── README.md

Compilation Pipeline

source.pie
    ↓ Lexer (NFA/DFA - Thompson's construction)
Tokens
    ↓ Parser (PLY LALR(1))
AST
    ↓ Semantic Analyzer (type checking, module resolution)
Validated AST
    ↓ LLVM Code Generator (llvmlite)
output.ll  (LLVM IR)
    ↓ clang + linker (runtime.c + module C sources)
./program  (native executable)

Compiler Usage

python3 src/main.py <source.pie>
./program

Intermediate files produced:

  • output.ll — LLVM IR (human-readable)
  • program — Final native executable

Changelog

See CHANGELOG.md for version history.


Made with ❤️ — Happy coding with PIE!

About

A Proof of concept compiler for a custom programming language

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages