py14
py14 copied to clipboard
Python to C++ 14 transpiler
Python to C++ 14 transpiler
:warning: This repository is no longer actively maintained by Lukas Martinelli.
This is a little experiment that shows how far you can go with the
C++ 14 auto
return type and templates.
C++14 has such powerful type deduction that it is possible to transpile
Python into C++ without worrying about the missing type annotations in python. Only a small subset of Python is working and you will encounter many bugs. The goal is to showcase the power of C++14 templates and not to create a fully functional transpiler.
Example
Original Python version.
def factorial(num):
if num <= 1:
return num
return factorial(num-1) * num
Transpiled C++ template.
template <typename T1> auto factorial(T1 num) {
if (num <= 1) {
return num;
}
return factorial(num - 1) * num;
}
How it works
Consider a map
implementation.
def map(values, fun):
results = []
for v in values:
results.append(fun(v))
return results
This can be transpiled into the following C++ template.
template <typename T1, typename T2>
auto map(T1 values, T2 fun) {
std::vector<decltype(
fun(std::declval<typename decltype(values)::value_type>()))> results{};
for (auto v : values) {
results.push_back(fun(v));
}
return results;
}
The parameters and the return types are deduced automatically In order to define the results vector we need to:
- Deduce the type for v returned from the values range
using v_type = typename decltype(values)::value_type
- Deduce the return type of
fun
for call with parameter vdecltype(fun(v))
- Because we dont know v at the time of definition we need to fake it
std::declval<v_type>()
- This results in the fully specified value type of the results vector
decltype(fun(std::declval<typename decltype(values)::value_type>()))
Trying it out
Requirements:
- clang 3.5
Transpiling:
./py14.py fib.py > fib.cpp
Compiling:
clang++ -Wall -Wextra -std=c++14 -Ipy14/runtime fib.cpp
Run regression tests:
cd regtests
make
Run tests
pip install -r requirements.txt
py.test --cov=py14
More Examples
Probability Density Function (PDF)
def pdf(x, mean, std_dev):
term1 = 1.0 / ((2 * math.pi) ** 0.5)
term2 = (math.e ** (-1.0 * (x-mean) ** 2.0 / 2.0 * (std_dev ** 2.0)))
return term1 * term2
template <typename T1, typename T2, typename T3>
auto pdf(T1 x, T2 mean, T3 std_dev) {
auto term1 = 1.0 / std::pow(2 * py14::math::pi, 0.5);
auto term2 = std::pow(py14::math::e, -1.0 * std::pow(x - mean, 2.0) / 2.0 *
std::pow(std_dev, 2.0));
return term1 * term2;
}
Fibonacci
def fib(n):
if n == 1:
return 1
elif n == 0:
return 0
else:
return fib(n-1) + fib(n-2)
template <typename T1> auto fib(T1 n) {
if (n == 1) {
return 1;
} else {
if (n == 0) {
return 0;
} else {
return fib(n - 1) + fib(n - 2);
}
}
}
Bubble Sort
def sort(seq):
L = len(seq)
for _ in range(L):
for n in range(1, L):
if seq[n] < seq[n - 1]:
seq[n - 1], seq[n] = seq[n], seq[n - 1]
return seq
template <typename T1> auto sort(T1 seq) {
auto L = seq.size();
for (auto _ : rangepp::range(L)) {
for (auto n : rangepp::range(1, L)) {
if (seq[n] < seq[n - 1]) {
std::tie(seq[n - 1], seq[n]) = std::make_tuple(seq[n], seq[n - 1]);
}
}
}
return seq;
}
Working Features
Only bare functions using the basic language features are supported.
- [ ] classes
- [x] functions
- [x] lambdas
- [ ] multiple inheritance
- [ ] operator overloading
- [ ] function and class decorators
- [ ] getter/setter function decorators
- [ ] list comprehensions
- [ ] yield (generator functions)
- [ ] function calls with
*args
and**kwargs
Language Keywords
- [ ] global, nonlocal
- [x] while, for, continue, break
- [x] if, elif, else
- [ ] try, except, raise
- [x] def, lambda
- [ ] new, class
- [x] from, import, as
- [ ] pass, assert
- [x] and, or, is, in, not
- [x] return
- [ ] yield
Builtins
- [ ] dir
- [ ] type
- [ ] hasattr
- [ ] getattr
- [ ] setattr
- [ ] issubclass
- [ ] isinstance
- [ ] dict
- [ ] list
- [ ] tuple
- [x] int
- [ ] float
- [x] str
- [ ] round
- [x] range
- [ ] sum
- [x] len
- [ ] map
- [ ] filter
- [ ] min
- [ ] max
- [ ] abs
- [ ] ord
- [ ] chr
- [ ] open
Data Structures
- [x] list
- [ ] Set
- [x] String
- [ ] Dict