Google has published Grumpy to convert Python code to Go.
Google Open Source Blog: Grumpy: Go running Python! google/grumpy: Grumpy is a Python to Go source code transcompiler and runtime.
Python has an ast module as standard, which allows direct access to parsing results.
import ast
node = ast.parse('''
def main() -> int:
print("Hello World!")
return 0
''')
print(ast.dump(node))
# Module(body=[FunctionDef(name='main', args=arguments(args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Str(s='Hello World!')], keywords=[])), Return(value=Num(n=0))], decorator_list=[], returns=Name(id='int', ctx=Load()))])
It seems that Grumpy also generates code while visiting the syntax tree with NodeVisitor. If you read it roughly, it seems that the result of visiting with Visitor is returned as a character string.
py2cpp
https://github.com/mugwort-rc/py2cpp
I remembered that I was working on a tool called py2cpp a while ago because I wanted to do the same thing in C ++.
Personally, when writing porting code, I often read it as the promised syntax of the porting language, but I was worried about how to express that processing, and when I visited with NodeVisitor, Transformer (preprocessing) and Hook (post processing) ), And output the wrapped Node so that it can be kneaded in various ways later.
(Output tuple
with std :: make_tuple
, replace the **
operator with std :: pow
...)
Hello World
$ cat samples/helloworld.py
def main() -> int:
print("Hello World!")
return 0
$ python -m py2cpp samples/helloworld.py
#include "py2cpp/py2cpp.hpp"
int main() {
std::cout << "Hello World!" << std::endl;
return 0;
}
range-based for
$ cat samples/range.py
def main() -> int:
x = 0
for i in range(100):
x += i
print(x)
return 0
$ python -m py2cpp samples/range.py
#include "py2cpp/py2cpp.hpp"
int main() {
x = 0;
for (auto i : py2cpp::range(100)) {
x += i;
}
std::cout << x << std::endl;
return 0;
}
The problem is that the first x = 0
type is missing, but other than that, I think that C ++ code that does not feel strange is being spit out.
I will give information on the type information later, or I think that auto is sufficient for this part, so I would like to improve it.
py2cpp :: range
is an alias that calls boost :: irange
using Variadic Templates.
$ cat samples/add.py
def add(x: float, y: float) -> float:
return x + y
def main() -> int:
print("2.0 + 3.0 =", add(2.0, 3.0))
return 0
$ python -m py2cpp samples/add.py
#include "py2cpp/py2cpp.hpp"
double add(double x, double y) {
return x + y;
}
int main() {
std::cout << "2.0 + 3.0 =" << add(2.0, 3.0) << std::endl;
return 0;
}
Introduced PEP483 type hints from Python 3.5.
This allows you to add type information to function arguments and return values.
Isn't it behaving pretty well?
If it is a program with simple logic, it may be near the future to write it in Python, convert it to C ++, and call it in Python using boost.python or [pybind11] 4.
py2cpp itself is published under GPLv3.
The products output using py2cpp are ** not GPL-infected, just like the GCC products **.
Py2cpp.hpp under include is published under Boost Software License.
I just remembered that I had a lot of things to do, such as determining the type and implementing the built-in function, so if you want to make Python code C ++ like me, edit it for a while and send a pull request. I would appreciate it if you could. It would be helpful if Pururiku is in Japanese. As you can see from Git's comments, English is inconvenient ...
[Bookworm: Google announces Grumpy, Python implementation by Go] 3
Recommended Posts