Focus Core

Mój pierwszy kompilator
xD Pozdrowienia dla dociekliwych xD

2007-11-04

Edytor FocusParser :)

W końcu małe co nieco :). Przepisałem parser pascala z pascala do mojego nowego języka do tworzenia parsherów :). Może to UberScript ? :) Raczej jego nagłówek.

Na pierwszy rzut oka można powiedzieć że wygląda dość masochistycznie i topornie, jednak w istocie jest to bardzo prosty, intuicyjny język (jego opis zamieszczę niebawem).

W drodze przetwarzania jest z niego generowana składnia w Pascalu. Język ten jest pierwszą z kilku warstw kompilatora. Zapraszam do oglądania i komentowania :)

Link Do Kodu Źródłowego

2007-11-02

Książka - "Kompilatory - Reguły, metody i narzędzia"

W końcu! :) Po dość długim czasie udało mi się zdobyć książkę którą miałem upatrzoną od dość dawna, aczkolwiek nie miałem sposobności na jej zdobycie. Raz, że była zbyt droga (160zł) a dwa nie byłem studentem. Jako, że obecnie "jeszcze" jestem studentem a w mojej bibliotece (o dziwo) są aż 3 egzemplarze tej książki, pokusiłem się o wypożyczenie jednej z nich :).

Co dalej? Pożyjemy - zobaczymy.

2007-10-23

Teoria Wizualnego Tworzenia Kompilatorów

W związku z pracami nad internetowym systemem DaThoX linki przestały działać - dzięki za spostrzeżenie - naprawiłem. Nastąpiła dość długa przerwa, spowodowana studiami, trochę też robotą dla mojego gamedev teamu. Nic to :). Zamierzam kontynuować dotychczasowe blogowe osiągnięcia - co najmniej jeden post na jeden miesiąc.

Podczas męczenia się z Uber Script powstała wizja narzędzia nadrzędnego dla "Uber Scripta" - mianowicie "Langu Age". Wizja systemu logicznego dla Kompilatorów. Jako, że na jednym kompilatorze (tudzież języku skryptowym JIT) nie chciałbym poprzestać, projektuję na wyrost techniki które chciałbym wykorzystać w przyszłości.

Langu Age - narzędzie trzymające wszystkie dane, struktury kompilatora w ramach spójnej całości. Prosta edycja wyrażeń regularnych, tworzenie błędów na poziomie wstępnego przetwarzania języka oraz logicznej analizy. Mam nadzieję, że moja wizja przyniesie wymierne korzyści :)

Chciałbym zauważyć iż nie wzoruję się na żadnym znanym rozwiązaniu a tworzą całość wg. mojej koncepcji (dzięki temu nie jestem w żaden sposób ograniczony - z jednej strony może powstać coś innowacyjnego a z drugiej coś gorszego od znanych rozwiązań). Oglądając różne kompilatory najbardziej mnie dobijała ich struktura - dość hermetyczne w wprowadzaniu ulepszeń (może moje subiektywne odczucie? a może widziałem zbyt mało przykładów).

Nic to :).

Langu Age powinien wspomagać następujące warstwy kompilatora:

Stream - Odpowiada za wczytywanie danych (z plików źródłowych). Jest dość potrzebna by zapewnić obsługę znaków UTF-8, UTF-16 etc.

Lexer - Wczytuje "język". Język nieco bardziej niskopoziomowy. Trudno mi to dokładnie nazwać z powodu mojej niewiedzy, ale chodzi o czyszczenie źródeł (pomijanie) "white chars" i wykrywanie błędów w stylu "Illegal character in input file: 'ą' ($B9)" w przypadku gdy np. słowa kluczowe czy też nazwy zmiennych nie mogą zawierać polskich znaków (składają się tylko z liter angielskiego alfabetu i +/- znaku w stylu _).

Log Lexer - Na podstawie wstępnie oczyszczonych źródeł przez warstwę Lexer, następuje przetwarzanie przez Log Lexer. Ta warstwa dba o logikę języka, zgłasza błędy wyższego poziomu - "Declaration expected but identifier 'xxx' found"

Script Lex / Optimisation - Trudna decyzja. Być może osobne warstwy a być może złączone w jedną. Dane przetwarzane przez Log Lexer będą zmieniane w język skryptowy (NIE JIT - więc jeśli nie dam rady zaimplementować wersji IA-64 i tak skrypty będą działać na 64 bitach ponieważ mój Uber Language będzie trawiony na kod Delphi a 64 bitowa wersja kompilatora Delphi jest już w drodze pod kodową nazwą Commodore64). Tylko pytanie - optymalizacje w trakcie zamiany na język skryptowy czy tuż po niej(?) (bardziej prawdopodobne jest pierwsze rozwiązanie).

Odnośnie Script Lex nie sposób nie wspomnieć iż przetrawiony kod na język skryptowy będzie wspólny dla różnych języków jakie będzie można tworzyć przez Langu Age i Uber Scripta. Zachowanie takie jest bardzo właściwe i pożądane - będzie można szlifować optymalizacje niezależnie od języka w którym programujemy :D, oraz dodawać platformy docelowe jakie dusza zapragnie - jedna baza danych, różne języki, i wiele platform (cel baaardzo daleki i abstrakcyjny :)).

Binary Code - Przetwarzanie języka skryptowego do plików pośrednich, skryptów JIT. Nic dodać nic ująć :).

Linker - Linkowanie do plików w stylu EXE, DLL...

Podsumowanie Langu Age

Koncepcja szalona. Projekt długoterminowy z niepewną przyszłością. Dziś wydaje się mało realny, jak wiele rzeczy o których myślałem kiedyś - nigdy tego nie napiszę (a dzisiaj działają w pełni ukończone :)).

nie wiem czy moja koncepcja jest słuszna i jak sobie poradzę z Mem Menagerem, RTTI i wieloma innymi mechanizmami. Jednak powoli i konsekwentnie. Na początek muszę dojść do celu realizując tylko części projektu - język skryptowy z moich marzeń.

2007-09-01

Parser

Plik: Parser_TEST.rar

Po wielu różnych parserah w końcu doszedłem do odpowiedniej jego formy. Zawsze wychodziły za bardzo oddalone od kompilacji/przetwarzania logicznego albo zbytnio z nim powiązane. Pierwszy raz mam poczucie, że to jest dokładnie to co być powinno :). Parsery można pisać na wiele sposobów - elastycznie (łatwo je dostosować do dowolnej składni) czy też sztywno - przeznaczone dla konkretnego języka (co może zaowocować wydajnością). Są też dostępne generatory parserów lecz te zupełnie mi nie odpowiadają. Po pierwsze zastanawiająca jest wydajność czegoś takiego, a po drugie chciałbym by UberScript był niezależny od zewnętrznych narzędzi - nie ma to jak być na swoich śmieciach ;).

To działa ;):
wykrywanie błędów na poziomie parsera (w stylu error_constant_expression_expected za znakiem # czy error_unterminated_string, error_syntax_error_in_real_number), składanie w locie stringów, czyli na przykład takiego czegoś: #72#$45'''Napis w apostrofach'''#$FFFFFFFFF#55' :D działa' w jednym "pop" :) (co chyba nie jest niczym nadzwyczajnym?). Mam radochę :D.

Parser jest tylko niewielką częścią UberScript jednak najważniejszą ponieważ całość (przetwarzanie logiczne, generowanie binarek) odwołuję się do niego setki razy i dlatego tak ważna jest jego wydajność, niezawodność i sposób przekazywania danych dalej.

TESTY. Może ktoś miałby ochotę posprawdzać czy Parser działa bez zastrzeżeń? Byłbym wdzięczny za wykrycie jak największej liczby błędów :P. (parser pisałem na 100% zgodności z parserem Delphi - mam nadzieję, że się udało). A błędy jak nie teraz to i tak wyjdą kiedyś przy okazji :)...

PS. Zrezygnowałem jedynie z zabytkowych Delphi Caret Chars (które nie działają już poprawnie w najnowszych wersjach Delphi).

PS.PS. Parser do wstawek asm będzie bardzo podobny, właściwie taki sam tylko z kosmetycznymi poprawkami (drugie apostrofy " " do napisów i specyficzne nazwy etykiet)

2007-08-25

Objconv - przybyłem, zobaczyłem i zmieniłem pliki pośrednie.

Nowe przemyślenia o pośrednim formacie (pliki gotowe do linkowania w binarkę) i odkrycia :).

OBJCONV

Przeszukując google we wszystkie strony (od niepamiętnych czasów szukałem jakiegoś "dobrego" programu do konwersji COFF na OMF i... w końcu znalazłem) odkryłem ciekawy i dość nowy program (tz. z tego roku tj. 2007) do konwersji nie tyle z COFF do OMF to i z OMF do COFF (!) i z wszystkiego na wszystko :). Jak dla mnie genialne, w dodatku z kodem źródłowym, drukuje informacje lepsze od TDUMP, a ponadto potrafi zdeasemblować te wszystkie binarki (w tym EXE i DLL!). Zwie się Objconv i można go ściągnąć pod tym adresem.

UNDNAME

Przydatna zabawka M$ potrafi odkodować nazwy procedur wyciągniętych z plików COFF. I tu się rozczarowałem :(. Pliki OMF *.obj generowane przez Borland są dużo bardziej skomplikowane od plików COFF *.obj m$ (swoją drogą zabawne jest to, że niektóre kompilatory wieloplatformowe GPL/LGPL C++/Pascala generują pliki COFF a nie OMF... Format COFF jest przystosowany pod Windowsowe pliki EXE a nie pod Linuxowe BINarki...). Szkoda, że tak ważne pliki o takim samym rozszerzeniu mają inną budowę. OMF bije na głowę pliki COFF (patrząc na logi z plików OMF a COFF i ich uniwersalność). Właściwie to szkoda, że mają taką zawiłą strukturę przystosowana pod obiektowe kodowanie - będę musiał zrezygnować z tych plików.

Z Delphi do C++ i z C++ do Delphi

Skoro jestem przy temacie, trudno nie napisać o moich nowych odkryciach :). Nie tak dawno usiłowałem przenieść ciekawy silnik 2D Haaf's Game Engine do Delphi (wzorowany na silniku Grim 2D, jednej z moich ulubionych gier : Crimsonland), przez Turbo C++ dzięki wspomnianym plikom OMF *.obj (które Delphi potrafi w siebie wkompilować). Niestety :(. Borland C++ generuje inne pliki omf niż Delphi x_X. Nie tyle co inne, tylko o bardziej skomplikowanej strukturze. To niesprawiedliwe! Pliki OMF generowane w Delphi, C++ Builder używa sprawnie... Całe szczęście, że programuję w Delphi :D. Dzięki temu nie będzie problemu gdybym chciał użyć mojego kod w C++ Builder, bo ten potrafi sobie sam wygenerować pliki *.hpp (nagłówki z przekonwertowanymi typami Delphi na kod C++ i procedurami), skompilować *.pas do OMF *.obj i używać go xD... Tylko po co mam to robić? Może kiedyś się przyda ;).

Z C do Delphi

Dobrze, że chociaż plików *.c można "prawie" używać w Delphi :). Najpierw trawimy je w C++ Builder a później wciskamy do Delphi przez {$L plik.obj} i uzupełniamy luki w procedurach o jakie woła wygenerowany *.obj (artykuł o tym jest tutaj). Tak można przenieść np. język LUA (bez DLL) do Delphi w kilka minut, przez *.obj.

Podsumowanie

Mój format pośredni będzie nieco inny od COFF czy OMF. Użyję czegoś wygodniejszego :) (jak pisałęm gdzieś niżej) i zyskam sporo czasu bo nie będę musiał tracić go na "dokładne" poznawanie wspomnianych formatów (w przyszłości). W końcu moje pliki binarne mają pełnić nieco inną rolę, będą to pliki pośrednie i zarazem gotowe skrypty. Mam nadzieję, że ktoś dożyje jeszcze do następnego posta :D - na razie priorytet to DaThoX i Delphi GameDev - ale... Niebawem przejdę do intensywnych prac nad GUI a tam przydałaby się pomoc szybkiego języka skryptowego JIT. A patrząc na to co jest, wyprodukowanie działającej wersji nie powinno być takie trudne (tylko skrypt i kod bez kompilowania do EXE) i zbyt zajmujące.

2007-07-09

Mniej Czasu

W związku z rozpoczęciem pracy nad grą w DaThoX będę miał mniej czasu na Focus Core. Jako, że Focus Core jest już nawet ładnym językiem a szkoda go tak zostawiać, więc trzeba zrobić upgrade celów. Zrezygnuję z Focus Core kompilatora, a zostanę przy pierwotnej koncepcji Focus Core Script (JIT x86).

2007-07-01

Format Plików

Kod przed zlinkowaniem do EXE będzie kompilowany do postaci pośredniej (tak jak pliki *.pas do *.dcu). Początkowo chciałem użyć plików *.obj (w wersji COFF [używany w C++ MS i innych] lub OMF [opcjonalnie generowany w Delphi i przez C++ Borlanda]), jednak jak na początek są zbyt nieporęczne i zupełnie zbędne (jedynie skomplikują proces kompilacji i linkowania i zabiorą sporo czasu na zapoznanie się z ich dokładną strukturą). Zresztą co tu dużo pisać - Focus Core ma być też skryptem i pliki wymyślone specjalnie dla FC będą mogły służyć jako skompilowane skrypty.

W przyszłości chciałbym zapewnić kompatybilność z COFF i OMF, a jak to będzie - zobaczymy.

Pliki z kodem. Mało to istotne jednak mam ochotę o tym napisać ;P

  • *.fpr - Focu Core Project (to co *.dpr)
  • *.f - Moduł z kodem (to co *.pas)
  • *.fcu - Focus Compiled Unit (podobnie jak *.dcu z tym, że będą mogły pełnić funkcję skompilowanych skryptów)
Niebawem bardziej użyteczne posty ;)...

2007-06-30

Uber Language

Przy tworzeniu języka focus core powstaje język do pisania kompilatorów. Jest to ciekawe rozwiązanie oszczędzające bardzo dużo pracy :) (jednocześnie jej nakładające, jednak z pewnością jest to opłacalne). Poza napisaniem dobrego skanera i analizatora składni (w Uber LAnguage) muszę oskryptować dane w IA32_DB. Robota idzie lekko xD. Dlaczego nie użyłem gotowych języków do definiowania składni? Po prostu nie odpowiada mi ich jakość/elastyczność, a ja chcę uzyskać możliwie najlepszy rezultat :). Jeśli Uber Language (mój język do tworzenia języków) spełni moje oczekiwania nie będzie stanowiło problemu zdefiniowanie samego Uber Language w Uber Language xD... A co za tym idzie? Dzięki takiemu rozwiązaniu UL będzie w stanie kompilować kompilatory nie tyle do postaci binarnych, co do innych języków (przykładowo natywny kompilator Pascala w php), niewielkim kosztem (rzędu kilkuset linijek kodu).

Uber Language jest tworzony mniej więcej od ostatniego newsa (23.06.2007) i na podstawie tego co jest muszę powiedzieć, że język w nim pisany jest duuużo czytelniejszy niż źródła Free Pascala, czy jakiegokolwiek innego kompilatora jaki widziałem (może to tylko subiektywne odczucie).

Zwariowane ale prawdziwe :). Jeszcze nie wiem czy udostępnię UL, ale jako rekompensatę postaram się za jakiś czas dostarczyć opis pliku pe exe, a przynajmniej pełnego tutka o tym jak wczytać i wygenerować sekcję importów, oraz zaprezentować jak wyglądają binarnie zapisane instrukcje asemblera (przynajmniej trudniejsze fragmenty związane z adresowaniem pamięci - opisy które znalazłem w internecie czy wyczytałem z książek były niekompletne i musiałem !ręcznie! analizować kody binarne w debugerze delphi...).

2007-06-23

Składnia FocusCore

Pierwsza wersja "Language RoadMap" gotowa :) (kliknij tutaj). Niby nic wielkiego ale jest się czego trzymać. Przede mną sporo roboty ^^. W końcu kompilator, compiler się rodzi ;). New news soon...

2007-06-22

Narzędzie IA32 DB

Aby nie pozostać gołosłownym zamieszczam dzisiaj moją bazę danych odnośnie instrukcji IA-32 (na bazie której wygeneruję kompilator) oraz program do jej przeglądania. Wszystko to (oraz dodatkowe informacje) znajduje się w tym archiwum.

2007-06-20

Focus Core - Własny Kompilator

Nazwa kodowa projektu "Focus Core" jak nazwa wskazuje ma mi przybliżyć działanie kompilatora. Ba :). Nie chodzi tu o czyste dociekanie ale i o stworzenie czegoś funkcjonalnego! Na razie nie będę przedstawiał planów na przyszłość mojego jednoosobowego projektu a jedynie na najbliższą teraźniejszość (lol "najbliższa teraźniejszość" xD).

Jako, że obecne życie mam zdaje się - jedno, postanowiłem 10 razy pomyśleć zanim coś większego zacznę pisać. Zagadnieniem języków programowania jestem zainteresowany od początków mojej kariery ;) programistycznej, i co należy dodać nie jestem w tej dziedzinie zupełnie zielony choć do do dojrzałości mojej jeszcze pod tym względem daleko ^^. Zastanawiałem się sporo czy pokazać to światu i oficjalnie coś pisać - doszedłem do wniosku, że tak. Wreszcie ruszę coś o czym zawsze marzyłem - kompilator i najszybszy skrypt, co pozwoli mi z większą radochą tworzyć inne projekty i umożliwi ich lepszą realizację.

Rezygnując ze zbędnego gadulstwa o mojej przeszłości i o tym co zrobiłem pragnę przedstawić koncepcję "Focus Core". Jako, że bardzo potrzebuję dobrego języka skryptowego postanowiłem na piedestał postawić cel stosunkowo ambitny, mianowicie skrypt typu IA-32. Jako, że od skryptu takiego do kompilatora nie jest już tak daleko przy okazji w ramach rozrywki (ale ze mnie rozrywkowy koleś xD) postanowiłem napisać kompilator.

Focus Core będzie jedynie (jedynie x_X) kompilatorem asemblera (na początek by później w języku który planuję nie było problemu z wstawkami asemblerowymi) z pełnym (a przynajmniej tak mi się wydaje) zestawem instrukcji IA-32 z pewnymi udogodnieniami. Wzorować się będę na asemblerze dostępnym w Delphi (etykiety, sposób zapisu danych czy liczb szesnastkowych z przedrostkiem $ itd.). Dodatkowo będę udostępniać część narzędzi które stworzyłem i stworzę, oraz przydatną dokumentację czy bazy danych (jako taką definicję języka który piszę postaram się dostarczyć do końca tygodnia).

Jako, że... Mam przykre doświadczenie z ręcznym wklepywaniem kodów maszynowych z dokumentacji i nie mam wsparcie ze strony Intela czy M$, początkowo postanowiłem sobie ułatwić zadanie i na podstawie dokumentacji wygenerować bazę danych na podstawie której wygeneruję kompilator :D.

Będą starał się sumiennie prowadzić tego bloga notując konsekwentnie moje postępy. Dodając co nieco, co kilka dni. Strona ta powstała jako auto-motywacja i kopniak do dalszego działania, która ma mi pokazać co już zrobiłem i co jeszcze mi zostało do zrobienia.

PS. Czekam na komentarze (nawet krytyczne ;( ), opinie i sugestie, będące niewątpliwie bodźcem do działania :)