-
1. Data: 2011-07-27 08:51:12
Temat: Prosty preprocesor wielojęzykowy
Od: "godek.maciek" <g...@g...com>
Witam wszystkich serdecznie,
przeglądając swoje archiwalne kody źródłowe, odkryłem, że napisałem kiedyś prosty
preprocesor. Pomysł polega na tym, że w pliku źródłowym programu można załączyć linie
@begin [command]
@end
która spowoduje wypisanie linii kodu zawartych pomiędzy znacznikami @begin i @end do
pliku $< oraz wykonanie polecenia [command] i załączenie treści pliku $> w miejsce
wystąpienia znaczników
Przykładowo, ktoś mógłby napisać w perlu (albo dowolnym innym języku) generator kodu
do języka c:
#include <stdio.h>
@begin "perl $< > $>"
print "int values[] = {\n";
for($i = 0; $i < 20; ++$i) {
print " $i,";
}
print " $i\n};\n";
@end
#define NELEMS(a)(sizeof(a)/sizeof(a[0]))
int main() {
int i;
for(i = 0; i < NELEMS(values); ++i) {
printf("%d, ", values[i]);
}
printf("\n");
return 0;
}
Po przepuszczeniu tego pliku przez preprocesor otrzymalibyśmy
#include <stdio.h>
int values[] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
};
#define NELEMS(a)(sizeof(a)/sizeof(a[0]))
int main() {
...
Przykład jest oczywiście zabawkowy, ale sam program napisałem z rzeczywistej
potrzeby.
Czy może słyszał ktoś, żeby podobne narzędzie już wcześniej istniało, albo żeby
realizowanie tego typu pomysłów było radykalnie odradzane przez jakieś
programistyczne autorytety?
Dla osób zainteresowanych załączam kod źródłowy programu (w perlu). Nie ma w nim
jakiejś większej głębi (nawet plik do przetworzenia trzeba podawać przy pomocy
operatora <, bo program obsługuje tylko standardowe wejście i wyjście). Narzędzie
można by było oczywiście rozwinąć, dodając np. opcję wyboru znaczników (bo @begin i
@end mogą się chyba kłócić z Objective-C)
Pozdrawiam serdecznie!
Panicz
elp.pl:
my @infile = <STDIN>;
my @modified;
use File::Temp qw/ tempfile tempdir /;
sub tempfname {
my $fh = File::Temp->new(TEMPLATE => 'elpXXXXX', SUFFIX => '.tmp');
return $fh->filename;
}
my $mode = 0; # 0 = regular (unprocessed) part of file, 1 = processed file
my $command; # your $wish
my $sourcefile; # $<
my $destfile; # $>
my $source = tempfname();
my $dest = tempfname();
for($i = 0; $i < @infile; $i++) {
if($infile[$i] =~ /^\@begin/) {
$mode = 1;
$firstquote = index($infile[$i], "\"");
$lastquote = rindex($infile[$i], "\"");
$length = $lastquote - $firstquote;
$command = substr($infile[$i], $firstquote+1, $length-1);
$command =~ s/\$</$source/g;
$command =~ s/\$>/$dest/g;
open($sourcefile, ">$source");
} elsif($infile[$i] =~ /^\@end/) {
$mode = 0;
close $sourcefile;
system($command);
open($destfile, "$dest");
while(<$destfile>) { print $_; }
close $destfile;
} elsif($mode == 0) {
print "$infile[$i]";
} elsif($mode == 1) {
print $sourcefile $infile[$i];
}
}
system("rm $source $dest");
-
2. Data: 2011-07-27 13:04:18
Temat: Re: Prosty preprocesor wielojęzykowy
Od: Adam Przybyla <a...@r...pl>
godek.maciek <g...@g...com> wrote:
> Witam wszystkich serdecznie,
> przeglądając swoje archiwalne kody źródłowe, odkryłem, że napisałem kiedyś prosty
preprocesor. Pomysł polega na tym, że w pliku źródłowym programu można załączyć linie
> @begin [command]
>
> @end
>
> która spowoduje wypisanie linii kodu zawartych pomiędzy znacznikami @begin i @end
do pliku $< oraz wykonanie polecenia [command] i załączenie treści pliku $> w miejsce
wystąpienia znaczników
>
> Przykładowo, ktoś mógłby napisać w perlu (albo dowolnym innym języku) generator
kodu do języka c:
> #include <stdio.h>
>
> @begin "perl $< > $>"
> print "int values[] = {\n";
> for($i = 0; $i < 20; ++$i) {
> print " $i,";
> }
> print " $i\n};\n";
> @end
... spoko, w bashu:
smtp:/home/adam>./test.sh
pelne
pelne
pelne
pelne
smtp:/home/adam>cat test.sh
#! /bin/sh
grep -v puste <<KONIEC
pelne
puste 1
pelne
puste 2
pelne
pelne
KONIEC
smtp:/home/adam>
Z powazaniem
Adam Przybyla
-
3. Data: 2011-07-27 13:39:27
Temat: Re: Prosty preprocesor wielojęzykowy
Od: Mariusz Marszałkowski <m...@g...com>
On Jul 27, 10:51 am, "godek.maciek" <g...@g...com> wrote:
> Witam wszystkich serdecznie,
> przeglądając swoje archiwalne kody źródłowe, odkryłem, że napisałem kiedyś prosty
preprocesor.
> Pomysł polega na tym, że w pliku źródłowym programu można załączyć linie
> @begin [command]
> @end
Nie wiem co to ma na celu... Mnie czasami nie chcialo sie wpisywac
recznie
wiele podobnego/specyficznego kodu. Wtedy pisalem po prostu w C taki
generator.
Czasami gdy musze napisac bardzo wydajny program, to marzy mi sie
zeby byl jakis pol-automatyczny konwerter z kodu ludzkiego na kod
zoptymalizowany. Niestety nie mam za bardzo pomyslu jakby to
moglo wygladac. Moze napisac jakis konwerter javy do c++, oczywiscie
podzbioru javy :)
Pozdrawiam
-
4. Data: 2011-07-27 22:03:04
Temat: Odp: Re: Prosty preprocesor wielojęzykowy
Od: "godek.maciek" <g...@g...com>
W dniu środa, 27 lipca 2011, 15:39:27 UTC+2 użytkownik Mariusz Marszałkowski napisał:
> Nie wiem co to ma na celu... Mnie czasami nie chcialo sie wpisywac
> recznie
> wiele podobnego/specyficznego kodu. Wtedy pisalem po prostu w C taki
> generator.
Moim zdaniem C nie jest najlepszym językiem do tworzenia generatora kodu, bo
zazwyczaj nie wymaga się od takich programów wydajności, ale raczej tego, żeby dało
się je szybko pisać i łatwo edytować, a nade wszystko -- żeby dobrze operowały na
łańcuchach tekstu. Ale nawet gdyby ktoś chciał zrobić coś takiego, to mógłby napisać
kod.c:
...
@begin "cc -x c $< -o gen; ./gen > $>; rm gen"
/* kod w C, który generuje inny kod w C */
...
@end
Tzn. ja sam raczej zalecałbym unikanie takiego stylu programowania (o ile istnieje
taka możliwość), jednak mogą się zdarzyć sytuacje, w których może on pozwolić na
zaoszczędzenie mnóstwa wysiłku i uniknięcie błędów.
Poza tym taki preprocesor pozwala na trzymanie kodów źródłowych kilku różnych
programów w jednym pliku tekstowym (co może mieć sens, gdy kody są niewielkie, a
programy mają ze sobą coś wspólnego) i zapewne można by dla niego wymyślić jeszcze z
miliard zastosowań :)
> Czasami gdy musze napisac bardzo wydajny program, to marzy mi sie
> zeby byl jakis pol-automatyczny konwerter z kodu ludzkiego na kod
> zoptymalizowany. Niestety nie mam za bardzo pomyslu jakby to
> moglo wygladac. Moze napisac jakis konwerter javy do c++, oczywiscie
> podzbioru javy :)
Trochę nie rozumiem, w jakim sensie kod w javie jest kodem ludzkim, i w jakim sensie
kod w c++ miałby być zoptymalizowany ;]
Zdaje się, że gcj oferuje możliwość kompilacji kodu w javie do postaci kodu
maszynowego x86 zamiast do kodu dla jvm.
Pozdrawiam!
-
5. Data: 2011-07-29 19:10:45
Temat: Re: Odp: Re: Prosty preprocesor wielojęzykowy
Od: Mariusz Marszałkowski <m...@g...com>
On Jul 28, 12:03 am, "godek.maciek" <g...@g...com> wrote:
> Moim zdaniem C nie jest najlepszym językiem do tworzenia
> generatora kodu, bo zazwyczaj nie wymaga się od takich
> programów wydajności, ale raczej tego, żeby dało się je
> szybko pisać i łatwo edytować, a nade wszystko -- żeby dobrze
> operowały na łańcuchach tekstu. Ale nawet gdyby ktoś chciał
> zrobić coś takiego, to mógłby napisać
Uzywalem kilku, raczej prostych generatorow kodu napisanych
w C/C++. Czyli program napisany w C/C++ generowal inny
program w C/C++. Fakt ze to byly proste i specjalistyczne
generatory, ale czy w innym jezyku bym uzyskal lepszy efekt?
Nie wiem... chyba nie, chyba jakbym te generatory pisal
w innym jezyku to bym musial sie napracowac tyle samo.
> Tzn. ja sam raczej zalecałbym unikanie takiego stylu programowania
> (o ile istnieje taka możliwość), jednak mogą się zdarzyć sytuacje, w
> których może on pozwolić na zaoszczędzenie mnóstwa wysiłku i
> uniknięcie błędów.
Bardzo czesto zdarza mi sie generowanie samych danych, np. tablic
w C/C++. Wtedy program wlasciwy ma gotowe wynik czesciowe.
> Poza tym taki preprocesor pozwala na trzymanie kodów źródłowych
> kilku różnych programów w jednym pliku tekstowym (co może mieć
> sens, gdy kody są niewielkie, a programy mają ze sobą coś wspólnego) i
> zapewne można by dla niego wymyślić jeszcze z miliard zastosowań :)
Zastanawiam sie nad zastosowaniem czegos w tym stylu do walidacji
krzyzowej. Czasami gdy musze napisac bardzo wydajny program to nikt
lacznie ze mna nie wie ile w nim pozostalo bledow.
> Trochę nie rozumiem, w jakim sensie kod w javie jest kodem ludzkim, i w
> jakim sensie kod w c++ miałby być zoptymalizowany ;] Zdaje się, że gcj
> oferuje możliwość kompilacji kodu w javie do postaci kodu maszynowego
> x86 zamiast do kodu dla jvm.
Ludzki w sensie bezpiecznego/porzadnego programowania. Przestrzeganie
wszelkich zasad ktore albo pomagaja uniknac bledow, albo pomagaja
udowodnic ze kod procedury jest poprawny. Do takiego kodu w javie
potem
zestaw makr (zamieszczanych chocby w komentarzach) ktore by
pomagaly/umozliwialy przekonwertowac jave na wydajny kod C/C++.
Albo moze w ogole jakis odrebny jezyk ktory by sie kompilowal zarowno
do C jaki i Javy.
Pozdrawiam
-
6. Data: 2011-07-30 12:52:25
Temat: Re: Odp: Re: Prosty preprocesor wielojęzykowy
Od: Spec <m...@g...com>
On 27 Lip, 18:03, "godek.maciek" <g...@g...com> wrote:
> W dniu środa, 27 lipca 2011, 15:39:27 UTC+2 użytkownik Mariusz Marszałkowski
napisał:
>
> > Nie wiem co to ma na celu... Mnie czasami nie chcialo sie wpisywac
> > recznie
> > wiele podobnego/specyficznego kodu. Wtedy pisalem po prostu w C taki
> > generator.
>
> Moim zdaniem C nie jest najlepszym językiem do tworzenia generatora kodu, bo
zazwyczaj nie wymaga się od takich programów wydajności, ale raczej tego, żeby dało
się je szybko pisać i łatwo edytować, a nade wszystko -- żeby dobrze operowały na
łańcuchach tekstu. Ale nawet gdyby ktoś chciał zrobić coś takiego, to mógłby napisać
>
> kod.c:
> ...
> @begin "cc -x c $< -o gen; ./gen > $>; rm gen"
> /* kod w C, który generuje inny kod w C */
> ...
Przychylam się do opinii że C to kiepski język do pisania generatorów.
Proponowałbym coś wyższego poziomu, oszczędności na pewno byłyby
większe.
>Czy może słyszał ktoś, żeby podobne narzędzie już wcześniej istniało, albo żeby
realizowanie tego typu pomysłów było radykalnie odradzane przez jakieś
>programistyczne autorytety?
Takie narzędzie, wbudowane w język programowania istnieje od ponad 50
lat - a język to Lisp.
Kod programu w Lispie przypomina AST, możemy więc mieszać kod i dane
bez ograniczeń. Najprostszy przykład:
`(a b c ,@(loop for i to 3 collect i))
"," wymusza wykonanie w danym miejscu tak więc od razu powstaje nam
lista elementów: (a b c 0 1 2 3).
Bardziej skomplikowane rzeczy możemy tworzyć z użyciem lispowych makr,
szybkie pokazanie możliwości: http://www.gigamonkeys.com/book/macros-defining-your
-own.html
-
7. Data: 2011-08-02 04:43:09
Temat: Re: Odp: Re: Prosty preprocesor wielojęzykowy
Od: Mariusz Marszałkowski <m...@g...com>
On Jul 30, 2:52 pm, Spec <m...@g...com> wrote:
> Przychylam się do opinii że C to kiepski język do pisania generatorów.
> Proponowałbym coś wyższego poziomu, oszczędności na pewno byłyby
> większe.
Te oszczednosci dzieki nowym jezykom programowania to w duzym
stopniu mit. Jak ktos nie ma wprawy w poslugiwaniu sie C to pewnie
ze nie napisze.
Dawno temu gdy PHP dopiero raczkowalo czesto serwisy internetowe
robilem w C. Mialem zestaw swoich libow... czesto nawet z bazy danych
nie korzystalem. Teraz www robie w PHP i SQL, tak wiec moge
porownac generowanie htmla w jezyku wysokopoziomowym i
niskopoziomowym. Podtrzymuje, ze jesli ktos jest wyrobiony w C, to
duzej roznicy nie ma. Ba... w ogromnych systemach moze sie
okazac ze w C bylo szybciej, bo tam decydujace znaczenie ma
jaki projekt zrobili a nie wybor jezyka.
> Takie narzędzie, wbudowane w język programowania istnieje
> od ponad 50 lat - a język to Lisp.
Jakby wygladal w lispie program ktory na wejscie pobiera
wektory uczace, buduje drzewo decyzyjne i wypluwa
procedure w C/C++ ktora realizuje to drzewo decyzyjne?
Ostatnio wlasnie taki generator w C++ pisalem ktory wypluwa
gotowy kod do wkompilowania w inny program. Nie znam
lispa a chcialbym miec porownanie.
Pozdrawiam
-
8. Data: 2011-08-03 01:01:21
Temat: Odp: Re: Odp: Re: Prosty preprocesor wielojęzykowy
Od: "godek.maciek" <g...@g...com>
W dniu sobota, 30 lipca 2011, 14:52:25 UTC+2 użytkownik Spec napisał:
> On 27 Lip, 18:03, "godek.maciek" <g...@g...com> wrote:
> > W dniu środa, 27 lipca 2011, 15:39:27 UTC+2 użytkownik Mariusz Marszałkowski
napisał:
> >
> > > Nie wiem co to ma na celu... Mnie czasami nie chcialo sie wpisywac
> > > recznie
> > > wiele podobnego/specyficznego kodu. Wtedy pisalem po prostu w C taki
> > > generator.
> >
> > Moim zdaniem C nie jest najlepszym językiem do tworzenia generatora kodu, bo
zazwyczaj nie wymaga się od takich programów wydajności, ale raczej tego, żeby dało
się je szybko pisać i łatwo edytować, a nade wszystko -- żeby dobrze operowały na
łańcuchach tekstu. Ale nawet gdyby ktoś chciał zrobić coś takiego, to mógłby napisać
> >
> > kod.c:
> > ...
> > @begin "cc -x c $< -o gen; ./gen > $>; rm gen"
> > /* kod w C, który generuje inny kod w C */
> > ...
>
> Przychylam się do opinii że C to kiepski język do pisania generatorów.
> Proponowałbym coś wyższego poziomu, oszczędności na pewno byłyby
> większe.
>
> >Czy może słyszał ktoś, żeby podobne narzędzie już wcześniej istniało, albo żeby
realizowanie tego typu pomysłów było radykalnie odradzane przez jakieś
>programistyczne autorytety?
>
> Takie narzędzie, wbudowane w język programowania istnieje od ponad 50
> lat - a język to Lisp.
> Kod programu w Lispie przypomina AST, możemy więc mieszać kod i dane
> bez ograniczeń. Najprostszy przykład:
> `(a b c ,@(loop for i to 3 collect i))
> "," wymusza wykonanie w danym miejscu tak więc od razu powstaje nam
> lista elementów: (a b c 0 1 2 3).
> Bardziej skomplikowane rzeczy możemy tworzyć z użyciem lispowych makr,
> szybkie pokazanie możliwości: http://www.gigamonkeys.com/book/macros-defining-your
-own.html
Osobiście jestem wielkim fanem lispa (choć jeżeli idzie o składnię makr, to preferuję
higieniczne makra schema z R5RS, po mimo tego, że pisze się je trudniej) -- jednak
one generują jedynie kod lispowy w lispie.
Nota bene, rzeczony preprocesor odgrzebałem, gdy pisałem w schemie skrypt generujący
kod w C, którego celem miało być udostępnienie funkcjonalności jakiejś biblioteki C++
interpreterowi guile.
Jeżeli idzie o maszynowe rzeczy niskopoziomowe w rodzaju sterowników, to chyba zawsze
będzie lepiej pisać je w C, bo to język wręcz stworzony do adresowania pamięci ;]
Ja na razie kombinuję, jak można by otrzymać kod w schemie, który po przetworzeniu
nie odbiegałby wydajnością od C i mógłby korzystać ze wszystkich bibliotek, które są
dostępne z poziomu C (przy zachowaniu takich dobrodziejstw lispa jak REPL)
W każdym razie - wracając do tematu - omówiony przeze mnie preprocesor to jednak coś
nieco innego niż defmacro, bo on jest poliglotą :)
pzdr
-
9. Data: 2011-08-03 02:00:31
Temat: Re: Prosty preprocesor wielojęzykowy
Od: A.L. <l...@a...com>
On Wed, 27 Jul 2011 01:51:12 -0700 (PDT), "godek.maciek"
<g...@g...com> wrote:
>Witam wszystkich serdecznie,
>przeglądając swoje archiwalne kody źródłowe, odkryłem, że napisałem kiedyś prosty
preprocesor. Pomysł polega na tym, że w pliku źródłowym programu można załączyć linie
>@begin [command]
>
>@end
>
>która spowoduje wypisanie linii kodu zawartych pomiędzy znacznikami @begin i @end do
pliku $< oraz wykonanie polecenia [command] i załączenie treści pliku $> w miejsce
wystąpienia znaczników
Tak, bardzo dawno pisalem takie rzeczy w AWK, cyba w latach 80.
Zreszta, AWK do dzis jest moim ulubionym narzedziem.
Tu jest bardzo wygodne narzedzie w podobnym stylu, tyle ze bardziej
zlozone
http://www.cparity.com/projects/AcmClassification/sa
mples/353484.pdf
Kod jest dostepny w wielu miejscach. Uzywam do generowania testow.
Testow w Prologu, zreszta...
A.L.