Stworzyłem kompilator w C (używając Lex & Bison) dla dynamicznego języka programowania, który obsługuje pętle, deklaracje funkcji wewnątrz funkcji, wywołania rekurencyjne itp. Stworzyłem również maszynę wirtualną, która uruchamia kod pośredni utworzony przez kompilator.
Myślałem o skompilowaniu go do kodu bajtowego Java zamiast własnego kodu pośredniego.
Widziałem, że pytanie o stworzenie języka JVM zostało już zadane , ale nie uważam odpowiedzi za zbyt pouczającą.
Oto moje pytania:
- Myślę, że aby stworzyć język dla JVM, koniecznością jest przeczytanie książki specyfikacji JVM , jakie inne książki możesz zasugerować (oprócz oczywiście Dragon Book)? Najbardziej niepokoją mnie książki lub samouczki dotyczące tworzenia języka JVM, a nie kompilator w ogóle.
- Istnieje wiele bibliotek Java do odczytu, zapisu i zmiany
.class
plików, takich jak jclasslib , bcel , kod bajtowy gnu itp. Którą z nich byś zaproponował? Czy wiesz również o bibliotekach C, które wykonują tę samą pracę? - Zastanawiałem się, czy przyjrzeć się innemu językowi, który jest przeznaczony dla JVM, takim jak Clojure, Jython lub JRuby. Ale wszystkie te języki są na bardzo wysokim poziomie i są skomplikowane (aby stworzyć dla nich kompilator). Szukałem prostszego (nie mam nic przeciwko, jeśli jest nieznany lub nieużywany), który jest przeznaczony dla JVM, a jego kompilator jest open source. Jakieś pomysły?
W zeszłym semestrze uczestniczyłem w kursie "Budowa kompilatora". Nasz projekt był dokładnie tym, co chcesz zrobić.
Językiem, którego użyłem do napisania mojego języka, była Scala . Działa na JVM, ale obsługuje wiele zaawansowanych funkcji, których Java nie ma (nadal jest w pełni kompatybilna z czystą Java JVM).
Do wyprowadzenia kodu bajtowego javy użyłem biblioteki Scala CAFEBABE . Dobrze udokumentowane i nie musisz zagłębiać się w klasy Java, aby zrozumieć, co robić.
Oprócz książki myślę, że możesz znaleźć wiele informacji, przeglądając laboratoria , które wykonaliśmy podczas kursu.
źródło
ASM może być rozwiązaniem do generowania kodu bajtowego. Na początek przejrzyj tematy dotyczące generowania elementów z instrukcji .
źródło
Sugestia: Możesz rzucić okiem na język programowania Lua , istnieją jego implementacje JVM, takie jak LuaJ .
(Nie mylić z LuaJava, który używa natywnych bibliotek z podejściem JNI).
źródło
W zeszły weekend zadawałem sobie to samo pytanie, aby przenieść język zabawek na JVM.
Spędzam tylko kilka godzin na szukaniu informacji, więc traktuj te odniesienia z przymrużeniem oka.
Wzorce implementacji języka . Nienawidzę antlr, ale ta książka wygląda bardzo dobrze. Jeśli nie lubisz antlr, jest bardzo dobre analizowanie „Techniki analizy. Praktyczny przewodnik”.
Rozdział 10 obejmuje 30 stron (do szybkiej IMO) tego tematu. Ale jest inny rozdział, który prawdopodobnie Cię zainteresuje.
Implementacja Lua 5.0 To świetny artykuł o maszynach z kodem bajtowym opartym na rejestrach. Idź i przeczytaj to nawet ze względu na to.
Lisp w małych kawałkach. Ta książka uczy, jak napisać 2 podręczniki szkolne, które można skompilować do C. Z tej książki można się wiele nauczyć. Posiadam egzemplarz tej książki i jest naprawdę dobra dla każdego, kto interesuje się seplenieniem, ale może nie twoja filiżanka herbaty.
http://www.amazon.com/Lisp-Small-Pieces-Christian-Queinnec/dp/0521562473
Sprawdź maszynę wirtualną Dalvik7, maszynę wirtualną opartą na rejestrze. DVM działa na kodach bajtowych, które są przekształcane z plików klas Java skompilowanych przez kompilator języka Java.
Istnieje lista dyskusyjna na ten temat, jvm-languages.
Czy planujesz załadować kod w dowolne miejsce? Chciałbym rzucić okiem.
źródło
Are you planning to upload the code to anyplace?
Nie jestem dumny z tego kodu :( ... może przepisałbym całość. W każdym razie, jeśli to zrobię, dam Ci znać. Dziękuję bardzo za sugestie.Poleciłbym najpierw dowiedzieć się, jak działa asembler JVM, jeśli jeszcze tego nie wiesz.
Wiele instrukcji ma postać
?name
, gdzie?
jest,i
jeśli instrukcja działa z typem całkowitym ia
jeśli działa z typem referencyjnym.Zasadniczo JVM jest maszyną stosową bez rejestrów, więc wszystkie instrukcje działają z danymi bezpośrednio na stosie. Możesz wypychać / przesuwać dane za pomocą
?push/?pop
i przenosić dane między zmiennymi lokalnymi (lokalizacjami stosu, do których odnoszą się przesunięcia), a szczytem stosu za pomocą?store/?load
. Inne ważne instrukcje toinvoke???
iif_???
.Podczas kursu kompilatora na moim uniwersytecie użyliśmy Jasmin do złożenia programów. Nie wiem, czy to najlepszy sposób, ale przynajmniej jest to łatwe miejsce do rozpoczęcia.
Oto lista instrukcji dla starej wersji maszyny JVM, która może zawierać mniej instrukcji niż nowa.
źródło
Najpierw wycofałem się, zmodyfikowałem kompilator tak, aby wyświetlał rzeczywistą Javę zamiast kodów bajtowych Javy (co oznacza tworzenie więcej translatora niż kompilatora) i kompilowałem dane wyjściowe Java z dowolnym wygodnym środowiskiem Java (które prawdopodobnie wygenerowałoby lepszy kod obiektowy niż mój własny kompilator).
Możesz użyć tej samej techniki (np. Skompilować do C #), aby wygenerować kody bajtowe CLI lub skompilować do Pascala, aby wygenerować kod P itp.
Nie jest jasne, dlaczego rozważasz użycie kodów Java zamiast używania własnej maszyny wirtualnej, ale jeśli chodzi o wydajność, oczywiście powinieneś również rozważyć kompilację do rzeczywistego kodu maszynowego.
źródło
Oczywiście kiedyś można było użyć Javy do napisania nowego języka. Dzięki API Refleksji w Javie możesz uzyskać plik llot. Jeśli prędkość nie ma większego znaczenia, preferowałbym Javę zamiast ASM. Programowanie w Javie (IMHO) jest łatwiejsze i mniej podatne na błędy . Spójrz na 7. język RPN . Jest w całości napisany w Javie.
źródło