A modern C++20 implementation of the Pangea programming language interpreter, ported from the original Java version.
- Modern C++20: Utilizes the latest C++ features including concepts, ranges, and std::variant
- Type-safe Value System: Robust value representation using std::variant
- Phrase-building Parser: Implements the unique phrase-building parsing mechanism
- Interactive Mode: REPL for experimentation and learning
- Comprehensive Testing: Full test suite using Catch2
- Cross-platform: Builds on Linux, macOS, and Windows
- C++20 compatible compiler (GCC 10+, Clang 12+, MSVC 2019+)
- CMake 3.20 or higher
- Catch2 (automatically fetched via CMake)
# Clone the repository
git clone <repository-url>
cd pangea-cpp
# Create build directory
mkdir build
cd build
# Configure and build
cmake ..
make
# Run tests
./tests/pangea_tests
# Run the interpreter
./src/pangea
For convenience, you can use the provided build script:
./scripts/build.sh
Start the interpreter without arguments to enter interactive mode:
$ ./pangea
Pangea C++ Interpreter
Type 'exit' to quit, 'help' for help.
pangea> println "Hello, World!"
Hello, World!
pangea> plus 2 3
=> 5
pangea> exit
Goodbye!
For better command line editing (history, arrow keys, etc.), use rlwrap
:
# Install rlwrap (if not already installed)
sudo apt-get install rlwrap # On Ubuntu/Debian
# or
brew install rlwrap # On macOS
# Run with enhanced editing
rlwrap ./pangea --interactive
In VS Code, you can use the "run pangea with rlwrap" task (Ctrl+Shift+P → "Tasks: Run Task" → "run pangea with rlwrap").
Run Pangea programs from files:
$ ./pangea examples/hello.pangea
Hello, World!
Execute code directly from the command line:
$ ./pangea -e "plus 2 3"
5
-h, --help
: Show help message-i, --interactive
: Start interactive mode-e, --eval CODE
: Evaluate code directly
Pangea uses a prefix notation with phrase-building semantics:
plus 2 3 # 5
minus 10 4 # 6
times 3 4 # 12
divide 15 3 # 5
power 2 3 # 8
plus "Hello, " "World!" # "Hello, World!"
length "hello" # 5
equal 5 5 # true
less 3 7 # true
greater 10 5 # true
and true false # false
or true false # true
not false # true
plus times 2 3 4 # (2 * 3) + 4 = 10
print "Hello" # Print without newline
println "Hello" # Print with newline
input # Read user input
type 42 # "number"
type "hello" # "string"
type true # "boolean"
number "42" # Convert to number
string 123 # Convert to string
pangea-cpp/
├── CMakeLists.txt # Main build configuration
├── README.md # This file
├── .github/
│ └── copilot-instructions.md
├── include/ # Header files
│ ├── value.hpp # Type-safe value system
│ ├── function_entry.hpp # Function registry and metadata
│ ├── parser.hpp # Tokenization and parsing
│ └── interpreter.hpp # Main interpreter class
├── src/ # Source files
│ ├── value.cpp
│ ├── function_entry.cpp
│ ├── parser.cpp
│ ├── interpreter.cpp
│ └── main.cpp
├── tests/ # Test files
│ └── test_main.cpp
├── examples/ # Example Pangea programs
│ ├── hello.pangea
│ ├── basics.pangea
│ └── types.pangea
└── scripts/ # Build and utility scripts
└── build.sh
The Value
class provides type-safe representation of all Pangea values using std::variant
:
- Numbers (double)
- Strings (std::string)
- Booleans (bool)
- Arrays (std::vector)
- Objects (std::unordered_map<std::string, Value>)
- Void (for functions with no return value)
The FunctionEntry
class manages function metadata and invocation:
- Function name and arity
- Built-in function implementations
- Type-safe parameter handling
The Parser
class handles:
- Tokenization with whitespace handling
- String literal parsing with quote support
- Comment removal (# to end of line)
- Input cleaning and normalization
The Interpreter
class implements:
- Phrase-building parsing mechanism
- Function call resolution and execution
- Built-in function library
- Stack management for calls and loops
plus a b
- Addition or string concatenationminus a b
- Subtractiontimes a b
- Multiplicationdivide a b
- Divisionpower a b
- Exponentiation
equal a b
- Equality testless a b
- Less thangreater a b
- Greater than
and a b
- Logical ANDor a b
- Logical ORnot a
- Logical NOT
print value
- Print without newlineprintln value
- Print with newlineinput
- Read user input
type value
- Get type namestring value
- Convert to stringnumber value
- Convert to numberlength value
- Get length
array
- Create empty arrayobject
- Create empty objectget collection key
- Get value from collectionset collection key value
- Set value in collection
if condition then else
- Conditional executiontimes_loop count body
- Loop executioneach collection body
- Iterate over collection
The project uses Catch2 v3 for unit testing. Tests are disabled by default to avoid dependency issues during the initial build.
mkdir build && cd build
cmake -DBUILD_TESTS=ON ..
make -j$(nproc)
The build system first tries to use system-installed Catch2 v3, and falls back to automatically downloading and building Catch2 v3.4.0 using CMake's FetchContent feature if not found.
To explicitly use FetchContent even if system Catch2 v3 is available:
cmake -DBUILD_TESTS=ON -DFORCE_FETCHCONTENT_CATCH2=ON ..
# Run all tests
./pangea_tests
# Run specific test
./pangea_tests "Value construction and type checking"
# Run tests with CTest
ctest --output-on-failure
# List available tests
./pangea_tests --list-tests
- Uses modern Catch2 v3 syntax and features
- Automatic test discovery via CTest
- Background FetchContent download ensures consistent testing environment
- Comprehensive unit tests for core components
- Follow the C++20 modern practices outlined in
.github/copilot-instructions.md
- Add tests for new features
- Update documentation as needed
- Use meaningful commit messages
This project is licensed under the MIT License - see the LICENSE file for details.
- Original Pangea interpreter implemented in Java
- Catch2 testing framework
- Modern C++ community for best practices and standards