Konwerter Python -> C++

0

Witam. Od jakiegoś czasu piszę konwerter j.w. Jeśli ktoś chce to może sobie zerknąć na stronie kod (w repozytorium svn). Kod jest dostępny dla wszystkich na licencji GNU GPL.

Idzie powoli, ale idzie. Jak się pojawi więcej czasu to może tempo wzrośnie. Jeśli ktoś chce coś poprawić/dodać/zmienić to byłbym bardzo wdzięczny.

Jeśli ktoś ma jakieś pytania to do soboty (07/04) południa jestem, później to dopiero od wtorku.

http://sourceforge.net/projects/surukuku
http://www.trac.cz/trac/surukuku

0

Pomysł w sumie ciekawy, tyle że nie jestem do końca pewny czy to ma sens - jeśli w znaczącym stopniu by to przyspieszało działanie programów napisanych w Pythonie to ok, ale jeśli tylko umożliwiałoby to kompilację to raczej bez sensu, już są takie projekty jak np. py2exe ;)

0

py2exe nie jest kompilatorem. W py2exe tworzony jest plik zip ze skryptami pythona i dołączany jest plik exe z interpreterem pythona. Wydajność takiego rozwiązania jest podobna jak samego pythona. To ma służyć jedynie jako ułatwienie w rozprowadzaniu programów pod windows.

Co do wydajności kodu C to zależy od tego co jest tłumaczone. Proste rzeczy bez skomplikowanych i czasochłonnych obliczeń zazwyczaj są 2-4 krotnie szybsze niż w pythonie. Kiedyś robiłem proste testy wydajności. Dla wielu pętli i obliczeń czas wykonania był w C mniejszy o ~212 razy.

Zaletą kodu C jest wydajność, ale także możliwość kompilacji do kodu maszynowego. Skrypty pythona można "skompilowac" do bytecodu, ale tu deassemblacja daje o wiele bardziej czytelny kod. Niektórzy wolą nieujawniać swojego kodu. Dodatkowo po przepisaniu do C nie jest wymagane posiadanie zainstalowanego interpretera.

Można się zapytać po co pisać w pythonie i konwertować na C jak można od razu w C pisać. Pisanie w pythonie trwa kilka razy krócej niż w C (są w sieci dostępne dokumenty na ten temat, głównie po angielsku).

0

Konwersja do modułów C:
Pyrex
SWIG
py2cmod

Jeżeli potrzeba tylko przyspieszyć to:
Psyco

Jeżeli przekonwertować do C, LLVM (a dalej do maszynowego) to:
PyPy

0

@Erihel -> czyli w takim razie pomysł całkiem niezły, jestem ciekaw co z tego wyjdzie ;) W Pythonie (mi przynajmniej) się naprawdę przyjemnie pisze więc każde przyspieszenie się przyda.

@Dryobates -> 3 pierwsze ciekawe, tyle że jak się domyślam program tak czy tak musi ruszyć z interpretera więc nie daje to tyle co 'pełny' translator.
Psyco - nie no fajnie, przyspieszenie za cenę dodatkowego zużycia pamięci. Jakoś mi się to nie widzi ;)
PyPy - to chyba jedyny z całej tej szóstki zgodny z założeniami programu Erihela ;) Tyle że on tłumaczy na C a nie C++, a to robi pewną różnicę.

0

Co z tego wyjdzie możesz już częściowo zobaczyć. Do kodu źródłowego dodanych jest 27 przykładów (16 z nich używa PyOpenGL).

Piszę i testuje pod 64bit Gentoo i nie bardzo mam jak sprawdzić czy się poprawnie kompiluje pod Windows. Jeśli użyjesz gcc pod windows (mingw czy cygwin) to powino ładnie działać.

Dla ścisłości bo niektórzy mają z tym problemy: p2cpp.py to tekstowy konwerter a p2cpp-gtk.py jak nazwa mówi okienkowy ;)

Pozdrawiam i znikam do wtorku, wesołych świąt wszystkim.

0
Ghostek napisał(a)

@Dryobates -> 3 pierwsze ciekawe, tyle że jak się domyślam program tak czy tak musi ruszyć z interpretera więc nie daje to tyle co 'pełny' translator.

True. Chyba, że potem py2exe potraktujesz, ale i tak w środku interpreter będzie siedział.

Psyco - nie no fajnie, przyspieszenie za cenę dodatkowego zużycia pamięci. Jakoś mi się to nie widzi ;)

Te dodatkowe zużycie pamięci najbardziej mnie martwi. Ale ogólnie uważam ideę za bardziej słuszną, niż kompilacja do C. Zachowujemy elastyczność języków dynamicznych, przy okazji optymalizując w locie, to co jest na prawdę istotne.

PyPy - to chyba jedyny z całej tej szóstki zgodny z założeniami programu Erihela ;) Tyle że on tłumaczy na C a nie C++, a to robi pewną różnicę.

Autor stale pisał o C, stąd i to C. Ale akurat nie sądzę, by to była znaczna różnica. Backendy można najróżniejsze tam przyczepić.

@Erihel
Ogólnie to bardzo dobrze, że powstaje taki projekt. Zawsze to coś na + dla społeczności pythona. Dodatkowe narzędzie.

Interesuje mnie bardzo, jak poradzisz sobie z dynamiczną naturą pythona, introspekcją oraz chyba najtrudniejszym do zrealizowania w "kompilowanych językach" zagadnieniem: metaklasy.

Znasz Objective-C? To jeden z niewielu kompilowanych, dynamicznych języków. Myślę, że znajomość jego mechanizmów (szczególnie mechanizmów kompilacji), pomogłaby Ci w pisaniu.

Życzę powodzenia.

0
Dryobates napisał(a)

Te dodatkowe zużycie pamięci najbardziej mnie martwi. Ale ogólnie uważam ideę za bardziej słuszną, niż kompilacja do C. Zachowujemy elastyczność języków dynamicznych, przy okazji optymalizując w locie, to co jest na prawdę istotne.

Nom, problem w tym że takie rozwiązanie raczej musi zużywać dodatkowo pamięć (bo gdzieś musi trzymać te dodatkowe tymczasowe kopie), a najczęściej jak program musi zużywać mało zasobów to wszystkich - czasu, procka, pamięci, itp. ;) Więc chyba jednak warto chyba poświęcić tą elastyczność (a poza tym, przecież raczej nikt by już takiego kodu po 'skompilowaniu' nie ruszał, przecież jak kompiluje się program w C++ to do kodu maszynowego w większości przypadków już nie ma po co zaglądać. Edytowałoby się wysokopoziomowy kod w Pythonie a kod C++ powoli stawałby się dla nowych programistów magicznymi zaklęciami możliwymi do zrozumienia tylko przez profesjonalistów i kompilatory ;) Kto wie, może to jest przyszłość języków programowania...) żeby tych zasobów mniej zużyć ;)

Interesuje mnie bardzo, jak poradzisz sobie z dynamiczną naturą pythona, introspekcją oraz chyba najtrudniejszym do zrealizowania w "kompilowanych językach" zagadnieniem: metaklasy.

Można by spróbować robić to tak jak kompilatory C++ radzą sobie z szablonami - robić tyle kopii danej funkcji/klasy ile razy jest wywoływana z różnymi typami. ;) (albo po prostu użyć szablonów z C++ ;))

0

Wiem, że python jest dynamicznym językiem. Cały czas myślę nad różnymi rozwiązaniami. Obecnie możliwe jest tłumacznie prostych zmiennych, które zmieniają w pythonie typ np.

a = 1 # mamy integer
a = 'jakis tekst' # mamy string

Używam przy pisaniu szablonów i zastanawiam się nad zabraniem za metaprogramowanie. Staram się, aby kod w C++ jak najbardziej przypominał ten z pythona żeby łatwiej było nanosić poprawki na przetłumaczony kod. Do tego celu także pisze nagłówki z różnymi typami i funkcjami (jak np. listy czy pliki).

Jest wiele do zrobienia, ale z czasem coraz więcej rzeczy implementuje. Chcę pare rzeczy uporządkować i zabrać się za słowniki oraz tuple.

Ghostek napisał(a)

W Pythonie (mi przynajmniej) się naprawdę przyjemnie pisze więc każde przyspieszenie się przyda.

To może pomógłbyś mi w testowaniu ? Bo sam to mam dostęp wyłącznie do komputerów z 32/64bit dystrybucjami linuxa.

Ogólnie to zachęcam wszystkich do testowania i ew. wysyłania mi skryptów, które nie działają (na razie najlepiej żeby dodatkowych modułów nie używały lub tylko wbudowanych w interpreter).

Postaram się do końca weekendu dodać na stronie projektu możliwość tłumaczenia skryptów prosto ze strony.

0

Jak mówiłem to daje http://surukuku.sf.net/convert.html . Jest problem i błąd. Jeśli się użyje % to kodu nie przetłumaczy. To wina wysyłania skryptu do cgi. Wysyłany jest na razie metodą GET ponieważ metoda POST nie działa za bardzo (tj. działa tylko kiedy wyśle dane ze skryptu np. pythona, a jak przez przeglądarke to skrypt cgi nie dostaje danych). Poprawiłem także kilka zauważonych błędów z silniku tłumaczącym.

0

Huh, ściągnąłem kod i próbowałem potestować, ale piszczy, że 'bad magic number' w pliku locale\pl_PL\surukuku.mo Domyślam się, że ów plik nie nadaje się do kopiowania 'na żywca' (a innej możliwości na stronie chyba nie ma, a nie specjalnie chce mi się instalować do tego specjalny program - do jednokrotnego użycia raczej się nie opłaca ;)), więc jeśli to nie będzie dla ciebie problemem mógłbyś podesłać mi ten plik na maila?

0

Pliki z tłumaczeniem nadają się do kopiowania 'na żywca'. Jak już pisałem wcześniej testowałem wyłącznie na linuksach, na których żadnych problemów nie było. Możliwe, że pliki pobrało po prostu uszkodzone lub wersja gettext jest starsza.

Używasz Windows ? Jeśli tak to może potrzebujesz gettext (http://gettext.sourceforge.net/).

Pliki mo można prosto otrzymać z załączonych z kodem plików tekstowych po:
msgfmt pl_PL.po -o pl_PL.mo

0
Erihel napisał(a)

Pliki z tłumaczeniem nadają się do kopiowania 'na żywca'.

A no tak, zmyliło mnie to że po otwarciu z hexedytora na początku był pozornie jednorodny blok bajtów (myślałem, że to efekt złego sposobu ściągnięcia ;)), ale jak się bardziej przyjrzeć to jednak aż taki jednorodny nie jest ;) To ok, popróbuję jeszcze i jak będę miał jakieś wyniki to dam znać.

EDIT:
Hmm, ale jak się tego gettexta używa? Próbowałem wkleić zawartość obu archiw do katalogu z ściągniętym twoim projektem i (!), potem do katalogu z pythonem i dalej nic. Próbowałem zmienić zmienną środowiskową LANG z pl na pl_PL i znowu (!), ciągle piszczy że 'bad magic number'. Szukałem po googlach, i jak widać jest to najoczywistsza rzecz w świecie, bo nigdzie o tym nie piszą. Nie wiem, może ze mnie jełop jakiś niewydarzony, ale dla mnie to takie znowu oczywiste nie jest ;) Pomoże ktoś?

0

Wysłałem maila kilka dni temu ze wskazówkami jak pominąć gettext. Postaram się o dostęp do komputera z windowsem i sprawdze co jest nie tak jak powinno.

0

Testujesz na Windowsie czy na Linuksie ? Sprawdziłem na Windowsie i się uruchomiło bez żadnych problemów i konwertowało ładnie i szybko. Jeśli na Linuksie to podaj dystrybucje, wersje pythona oraz gettext (gettext -V).

0

Wysłałem maila kilka dni temu ze wskazówkami jak pominąć gettext.

Dzięki, po poprawkach które podałeś działa ;)

Testujesz na Windowsie czy na Linuksie?

Windows, XP konkretnie.

Co do samego programu, to o ile przykłady tłumaczy całkiem nieźle, chociaż mam pewne zastrzeżenia:
Po 1 - dając 'using namespace std;' w nagłówku zaśmiecasz globalną przestrzeń nazw w każdym pliku, który go dołącza. IMHO nie jest to najlepszy pomysł ;)
Po 2 - w kodzie czasem pojawiają się nie wiadomo po co utworzone zmienne tymczasowe. Np. w

// wynik tłumaczenia fib.py
#include "fib.h"

	void fib( float n )
	{
		int a, b, __1;
		a = 0; b = 1;
		while ( b < n )
	{
			__1 = b; b = (a + b);
			a = __1;
			cout << a << endl;
			}
		}

int main( int argc, char **argv )
{
	fib( 100 );
	fib( 1.2 );
	return 0;
}

zmienna __1 jest zupełnie niepotrzebna ;)
Po 3 - co do powyższego przykładu - to formatowanie mnie troszkę przeraża :) Nie jest to jakiś straszny problem, ale jeśli kod ma się nadawać do czytania i poprawiania po tłumaczeniu, to... ;)
Po 4 - czy w wypadku wywoływania jednej funkcji z argumentami różnych typów, zamiast tworzyć wersję z typem najbardziej 'pojemnym' nie lepiej by było ją przeciążać, albo nawet i zrobić z niej szablon?

No i jak próbowałem przetłumaczyć mój kod (trochę za długie, żeby na forum umieszczać, jak chcesz to mogę ci na maila podesłać. Jakby co: zawiera jedną klasę - implementacje drzewa - z jedną klasą zagnieżdżoną Node i metodami do najważniejszych operacji), to python przy interpretowaniu p2cpp w 1240 linii pliku parser.py

for It in self.Functions[self.CurrentFunc-1]['temp']:

(dochodzi do tego z linii 116 pliku p2cpp.py, 'compiler.walk(code, parser)') wywala list index out of range.
W pythonie jestem niestety trochę za cienki bolek (może jakby to w cpp było... ;)), żeby choćby i próbować szukać w twoim kodzie przyczyny tego błędu (lub też czemu mój kod nie nadaje się do tłumaczenia przez program, jakby co żadnych zewnętrznych - nawet i standardowych - modułów nie użyłem ;)), więc tylko informuję ;)

0

Ad.1 Zgadzam się i mam przebudować przestrzenie nazw.

Ad.2 Da się w C wykonać następujące przypisanie (tuple = tuple) bez dodatkowej zmienej ?
a, b = b, a+bDokładnie to oznacza, że dla a przypisujemy b, a dla b przypisujemy a+b, ale to a bierzemy zamim dostało wartość z b.

Ad.3 Formatowanie mam poprawić. Taki kwiatek się pojawił po zmaianach z przestrzeniami nazw.

Ad.4 Wyślij mi ten kod na maila.

0

Da się w C wykonać następujące przypisanie (tuple = tuple) bez dodatkowej zmienej ?

No jak już przerabiać to na:

__1 = b; b = (a + b);

czyli robić 2 instrukcje cpp z jednej pythonowej, to równie dobrze można b += a; a = b;

 ;)
0
Ghostek napisał(a)

Da się w C wykonać następujące przypisanie (tuple = tuple) bez dodatkowej zmienej ?

No jak już przerabiać to na:

__1 = b; b = (a + b);

czyli robić 2 instrukcje cpp z jednej pythonowej, to równie dobrze można b += a; a = b;

 ;)

Dla a = 5, b = 6 Twój kod da a = 11 oraz b = 11 kiedy prawidłowy wynik dla pythona to a = 6 oraz b = 11.
0

No ok, pomyłka ;) Jednak się bez tej dodatkowej zmiennej nie obędzie. Ale reszta punktów pozostaje nadal aktualna.

0

Strona do konwertowania skryptów powinna już działać prawidłowo. Poprawiam błędy i implementuje rzeczy, które sobie zaplanowałem. Klasy są na razie potraktowane po macoszemu, ale jak się uporam z tym co mam na liście to wezme się ostro za klasy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1