Pome is a compact, interpreted programming language created as a learning project to explore interpreter design and implementation. It demonstrates fundamental concepts in language design including lexing, parsing, AST traversal, and runtime value management. The language features dynamic typing, object-oriented programming capabilities, garbage collection, and a modular system for code organization. Built entirely in C++, Pome serves as an educational foundation for understanding how programming languages work internally.
Note: Pome is supposed to be a successor of an old interpreted programming language I made. I improved the underlying architecture and extended its capabilities so I can potentially use it for actual programming tasks and to learn more about programming languages ecosystems.
- Dynamic Typing: No explicit type declarations required. Types are inferred at runtime.
- Object-Oriented Programming: Full support for classes, inheritance, and methods with the
thiskeyword. - Functions: First-class functions with closures and higher-order function support.
- Control Flow: Complete support for
if/else,while, andforloops. - Operators: Comprehensive operator support including arithmetic, comparison, logical, and assignment operators.
- Ternary Operator: Conditional expressions for concise control flow.
- Native Extensions: Extend Pome with high-performance C++ modules loaded dynamically (
.so,.dll). - Module System: Import and export modules for better code organization and reusability.
- Garbage Collection: Automatic memory management with mark-and-sweep GC.
- Standard Library: Built-in functions and modules:
- math: Mathematical operations including
sin,cos,random, and constants likepi. - string: String manipulation utilities like
sub(substring). - io: File I/O operations (
readFile,writeFile). - print: Universal output function.
- math: Mathematical operations including
- Primitives:
nil,true/false, numbers (integers and floats) - Collections: Lists and Tables (associative arrays/dictionaries)
- Complex Types: Functions, Classes, and Instances
- C++17 compatible compiler (GCC, Clang, or MSVC)
- CMake 3.10 or higher
# Clone the repository
cd Pome
# Create a build directory
mkdir build
cd build
# Configure and build
cmake ..
make
# Run a Pome script
./pome ../examples/demo.pomePome scripts are plain text files with the .pome extension:
./pome script.pomeFor comprehensive guides on the Pome language, visit the docs/ directory:
- Getting Started - Installation and first program
- Language Fundamentals - Variables, types, and basic syntax
- Control Flow - Conditionals and loops
- Functions - Functions, closures, and higher-order functions
- Object-Oriented Programming - Classes and objects
- Collections - Lists and tables
- Operators Reference - Complete operator guide
- Module System - Code organization and imports
- Standard Library - Built-in functions and modules
- Error Handling - Debugging and testing
- Advanced Topics - Advanced patterns and techniques
- Architecture - Internal design and implementation (for contributors)
- Native Extensions - Writing C++ modules (FFI)
var x = 10; // Integer
var y = 3.14; // Float
var message = "Hello"; // String
var flag = true; // Boolean
var nothing = nil; // Nil (null equivalent)
var items = [1, 2, 3]; // List
var person = { // Table (dictionary)
name: "Alice",
age: 30
};
// If-Else Statements
if (x > 0) {
print("Positive");
} else if (x < 0) {
print("Negative");
} else {
print("Zero");
}
// While Loop
var counter = 0;
while (counter < 5) {
print(counter);
counter = counter + 1;
}
// For Loop
for (var i = 0; i < 3; i = i + 1) {
print("Iteration:", i);
}
// Ternary Operator
var result = x > 0 ? "positive" : "non-positive";
// Function declaration and call
fun add(a, b) {
return a + b;
}
var sum = add(5, 3); // sum = 8
// Anonymous functions (closures)
fun makeCounter() {
var count = 0;
return fun() {
count = count + 1;
return count;
};
}
var counter = makeCounter();
print(counter()); // 1
print(counter()); // 2
// Class definition
class Dog {
fun init(name) {
this.name = name;
this.sound = "Woof";
}
fun speak() {
print(this.name, "says", this.sound);
}
fun setSound(s) {
this.sound = s;
}
}
// Creating and using instances
var dog = Dog("Buddy");
dog.speak(); // Output: Buddy says Woof
dog.setSound("Bark");
dog.speak(); // Output: Buddy says Bark
print(dog.name); // Output: Buddy
// Exporting from a module (in my_module.pome)
export fun add(a, b) {
return a + b;
}
// Importing and using a module
import my_module;
var result = my_module.add(5, 3);
// Using built-in modules
import math;
import string;
import io;
print("PI:", math.pi);
print("Substring:", string.sub("Hello", 0, 3));
io.writeFile("output.txt", "Hello, Pome!");
math.pi- Pi constantmath.sin(x)- Sine functionmath.cos(x)- Cosine functionmath.random()- Random number between 0 and 1
string.sub(str, start, end)- Extract substring
io.readFile(path)- Read file contentsio.writeFile(path, content)- Write content to file
print(...)- Print values to stdoutlen(collection)- Get length of list or tabletype(value)- Get type name of value
Pome/
├── CMakeLists.txt # CMake build configuration
├── assets/
│ └── logo.png # Project logo
├── include/ # Header files
│ ├── pome_lexer.h # Tokenization
│ ├── pome_parser.h # Parsing to AST
│ ├── pome_interpreter.h # Execution engine
│ ├── pome_value.h # Runtime value types
│ ├── pome_environment.h # Variable scoping
│ ├── pome_stdlib.h # Built-in library
│ ├── pome_gc.h # Garbage collector
│ ├── pome_importer.h # Module system
│ ├── pome_ast.h # AST node definitions
│ └── pome_errors.h # Error handling
├── src/ # Implementation files
│ ├── main.cpp # Entry point
│ ├── pome_lexer.cpp # Lexer implementation
│ ├── pome_parser.cpp # Parser implementation
│ ├── pome_value.cpp # Value type implementation
│ ├── pome_environment.cpp# Environment implementation
│ ├── pome_interpreter.cpp# Interpreter implementation
│ ├── pome_stdlib.cpp # Standard library implementation
│ ├── pome_gc.cpp # Garbage collector implementation
│ └── pome_importer.cpp # Module system implementation
├── examples/ # Example Pome scripts
│ ├── demo.pome # Basic language features
│ ├── test_class.pome # Object-oriented examples
│ ├── test_stdlib.pome # Standard library usage
│ ├── test_for_loops.pome # Loop examples
│ ├── test_math.pome # Math operations
│ └── ... # Additional examples
├── test/ # Test files
└── build/ # Build artifacts (generated)
Pome follows a classic interpreter architecture, split into a shared library (libpome) and a CLI executable:
- Lexer (
pome_lexer): Tokenizes source code into a stream of tokens. - Parser (
pome_parser): Builds an Abstract Syntax Tree (AST) from tokens. - Interpreter (
pome_interpreter): Walks the AST and executes the program. It resides in the shared librarylibpome. - Value System (
pome_value): Represents runtime values and objects. - Environment (
pome_environment): Manages variable scopes and bindings. - Standard Library (
pome_stdlib): Provides built-in functions and modules. - Garbage Collector (
pome_gc): Automatically manages memory. - Module System (
pome_importer): Handles code organization and dynamic imports of both.pomescripts and native C++ extensions.
print("Hello, World!");
fun fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
for (var i = 0; i < 10; i = i + 1) {
print("fib(" + i + ") = " + fibonacci(i));
}
class Calculator {
fun init() {
this.result = 0;
}
fun add(x) {
this.result = this.result + x;
return this;
}
fun multiply(x) {
this.result = this.result * x;
return this;
}
fun getResult() {
return this.result;
}
}
var calc = Calculator();
var answer = calc.add(5).multiply(3).getResult();
print("Result:", answer); // Output: Result: 15
import io;
// Write to file
io.writeFile("greeting.txt", "Hello from Pome!");
// Read from file
var content = io.readFile("greeting.txt");
print("File contents:", content);
Current version: 0.2.0
- Linux: Full support
- macOS: No idea (I don't own a mac)
- Windows: Not yet.
Contributions are welcome! Please feel free to submit pull requests or open issues for bugs and feature requests.
This project is licensed under the MIT License - see the LICENSE file for details.
Pome was created as a learning project to understand the fundamental concepts behind programming language implementation. Through building Pome, I explored:
- Lexical Analysis: Tokenizing source code
- Syntax Analysis: Building Abstract Syntax Trees
- Semantic Analysis: Type checking and scope management
- Runtime Execution: Interpreting and executing code
- Memory Management: Implementing garbage collection
- Modularity: Building an extensible module system
This refactored version improves upon the original implementation with better code organization and architecture.
Pome draws inspiration from languages like Lua, Python, and Lox. Languages known for their clarity and educational value in language design.
Happy Pome-ming! 🍎✨
