Low-level C++ REPL (like Python REPL) built on LLVM VM concept.
- VM core:
llvm::orc::LLJIT– in-process JIT, no optimization initially - Frontend:
clang::Interpreter(incremental parser + ORC executor) for real C++ parsing - REPL: incremental state, value printing, diagnostics,
:commands
User Input (raw C++ like Python, no main)
│
▼
┌─────────────────────────────────────────┐
│ cli::parse (src/cli) │ ← Options, --scaffold, -e, files
└──────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ utils::VersionDetector (src/utils) │ ← auto-detects C++17/20/23 via keywords
│ import, concept, requires, co_await │
└──────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ interpreter::Interpreter (src/interpreter) │ ← wraps clang::Interpreter + ORC JIT
│ + utils::BigIntSupport preamble │ auto -std=c++17/20/23, bigint
└──────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ core::VM / LLJITVM (src/core) │ ← llvm::orc::LLJIT, pluggable backends
│ IR: LLVMContext, Module, IRBuilder │
└──────────────┬──────────────────────────┘
▼
┌─────────────────────────────────────────┐
│ repl::Session (src/repl) │ ← prompts, multiline, :commands, history
└─────────────────────────────────────────┘
Scalable: each layer is an isolated module with interface, easy to swap VM (e.g. RemoteJIT), add new frontends, or extend utils (BigInt, version).
No optimizations (O0) – correctness first.
Requires LLVM 22 + Clang 22 (with clangInterpreter).
cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j
./build/cpp-replcpp-repl [options] [file ...]
-h, --help show help
-v, --version show version (0.2.0 + LLVM 22.1.3)
--scaffold show low-level VM IR demo (hidden by default)
--no-interactive exit after file/-e execution (script mode, like python)
-e <code> execute raw C++ code (no main needed)
-I <path> add include path (absolute or relative, repeatable)
-L <path> add library search path
-l <lib> link library (e.g. -l m -l gmp, also .so path)
-D <macro> define macro (e.g. -DDEBUG=1)
--include <path> same as -I
--library <lib> same as -l
<file> execute raw C++ file as script (like python script.py)Examples (no int main() required, just raw C++ like Python):
./build/cpp-repl # interactive REPL, raw code
./build/cpp-repl examples/hello.cpp # run file as script then REPL
./build/cpp-repl --no-interactive examples/hello.cpp # script only
./build/cpp-repl -e 'int x=5; x*2' --no-interactive # -e raw code
echo 'int x=42; x+1' | ./build/cpp-repl # pipe like python
echo 'cpp_int a = cpp_int("12345678901234567890"); a*a' | ./build/cpp-repl
# absolute & relative includes + libraries (cmdline)
./build/cpp-repl -I ./include -I /abs/path -L ./lib -l mylib -e '#include "myheader.h"'
./build/cpp-repl -I ./rel_include --library m --no-interactive -e 'extern "C" int mylib_add(int,int); mylib_add(2,3)':help :h show help
:quit :exit :q exit REPL
:dump dump history + current C++ version
:reset reset interpreter state
:load <file> load raw C++ file
:lib <path> load dynamic library (abs/rel, e.g. :lib ./lib/mylib.so)
:I <path> add include search path (abs or rel, like -I)
:L <path> add library search path (like -L)
:undo [n] undo last n
:version show current -std version
Both absolute (/usr/local/include/mylib.h) and relative (./include/mylib.h, ../common/header.h) are supported.
Cmdline (like g++ -I/-L/-l):
# Include: absolute + relative
cpp-repl -I ./rel_include -I /tmp/abs_include -e '#include "myheader.h"'
# Library: absolute .so path, or -L + -l search
cpp-repl -l /tmp/abs_mylib.so -e 'extern "C" int mylib_add(int,int); mylib_add(5,10)'
cpp-repl -L ./tmp_lib -l mylib -e 'extern "C" int mylib_add(int,int); mylib_add(2,3)'
cpp-repl -I ./include -L ./lib -l mylib --library gmp -D DEBUG=1
# Combined with file/script
cpp-repl -I ./include -L ./lib -l mylib examples/use_mylib.cpp --no-interactiveInteractive (inside REPL):
cpp> :I ./rel_include // relative
cpp> :I /tmp/abs_include // absolute
cpp> #include "myheader.h" // now found
cpp> rel_func() // (int) 200
cpp> :L ./tmp_lib
cpp> :lib mylib // bare -l name, searches -L paths
cpp> :lib ./tmp_lib/libmylib.so // absolute/relative .so
cpp> extern "C" int mylib_add(int,int);
cpp> mylib_add(7,8) // (int) 1015Paths are stored and survive C++ version upgrades (e.g. adding :I then concept → still keeps includes).
Interpreter auto-detects required -std:
- C++17 default
- C++20 if code contains
concept,requires,co_await,co_yield,char8_t,<=>,consteval - C++23 if code contains
import,module/export
Example:
cpp> template<typename T> concept Addable = requires(T a,T b){ a+b; };
cpp> Addable auto x = 42; // auto-detects C++20, re-inits to -std=c++20
cpp> import std; // C++23No manual -std needed.
Like Python's arbitrary large ints, via boost::multiprecision:
cpp> cpp_int a = cpp_int("1234567890123456789012345678901234567890");
cpp> cpp_int b = cpp_int("987654321098765432109876543210");
cpp> cpp_int c = a * b; c // prints big int
cpp> bigint x = cpp_int("999999999999999999999999999999"); // alias
cpp> x * xbigint is boost::multiprecision::cpp_int (header-only). If GMP is installed,
also boost::multiprecision::mpz_int / gmp.hpp is available and linked via -lgmp -lgmpxx.
Demo: examples/bigint.cpp
See examples/:
hello.cpp– basic I/O and value printingfunctions.cpp– incremental function definitions (persistence)class.cpp– structs, classes, templates
Load with :load examples/hello.cpp or ./build/cpp-repl examples/class.cpp
include/cpp-repl/core/vm.h+src/core/vm.cpp– rawllvm::orc::LLJITwrapper viacore::VMinterface (pluggable, scalable). Manually builds LLVM IR (LLVMContext,Module,IRBuilder) and JIT-executes without Clang.include/cpp-repl/interpreter/interpreter.h–interpreter::Interpreterwrapsclang::Interpreter(incremental) +VersionDetector+BigIntSupportpreamble. Handles raw code withoutmain.- Legacy
src/vm.h/src/repl.hkept as wrappers for backward compat.
No optimizations: all builds are -O0 -g -fno-exceptions -fno-rtti to stay close to the VM.
include/cpp-repl/
core/vm.h
interpreter/interpreter.h
utils/version_detector.h, bigint.h
repl/session.h
cli/cli.h
src/
core/vm.cpp
interpreter/interpreter.cpp
utils/version_detector.cpp, bigint.cpp
repl/session.cpp
cli/cli.cpp
main.cpp (scalable, delegates to modules)
examples/
hello.cpp, functions.cpp, class.cpp, bigint.cpp, version_concept.cpp
- CI (
ci.yml): Ubuntu 24.04, LLVM 22,Debug+Release, smoke tests (-e, pipe, examples, BigInt, C++20 concepts) - Format (
format.yml):clang-format-22+ whitespace +cppcheck - CodeQL (
codeql.yml): weekly security analysis (C++) - Release (
release.yml): builds tarball onv*tags viasoftprops/action-gh-release
Enable branch protection on main to require Build (ubuntu-24.04, Debug, LLVM 22) before merge.
MIT — see LICENSE