Mengembangkan bahasa yang dinamis


11

Saya telah membuat beberapa kompiler tulisan tangan untuk bahasa yang sangat sederhana, tetapi sekarang saya ingin mencoba mengembangkan bahasa yang dinamis, mirip dengan Python atau Ruby yang disederhanakan. Namun, mudah bagi saya untuk membungkus kepala saya di sekitar bagaimana kompiler bekerja. Kompiler primitif baru saja menerjemahkan. Tetapi saya tidak bisa melakukan ini jika bahasanya dinamis. Saya harus menulis penerjemah atau VM yang melacak informasi saat runtime dan memberikan lebih banyak pekerjaan pada saya.

Singkatnya, apakah ada sumber daya yang harus saya periksa mengingat saya tahu bagaimana kompiler bekerja tetapi ingin bermigrasi untuk membuat juru bahasa? Ada beberapa VM di luar sana untuk bahasa dinamis, tapi saya tidak punya masalah dengan menggulirkan saya sendiri. Ini semua hanya untuk pengalaman pribadi saya.

Saya mencari informasi tentang cara beralih dari kompiler ke juru bahasa. Jika saya sudah membuat kompiler untuk bahasa X tapi sekarang apa yang harus ditulis juru bahasa, apa yang perlu dilakukan dan apakah ada sumber daya yang melewati proses?

Saya tidak ingin sumber daya yang luas atau abstrak yang membahas bagaimana kompiler atau mesin virtual bekerja. Saya punya banyak buku pelajaran tentang masalah ini. Semua sumber yang saya temukan online mengasumsikan Anda memiliki pengalaman 0 dan dengan demikian memulai Anda dengan analisis leksikal atau sintaksis atau mereka sangat abstrak. Saya memiliki kompiler yang berfungsi, tetapi sekarang saya ingin mengubahnya menjadi penerjemah dan menambahkan fitur dinamis ke bahasa.

Saya tidak dapat menemukan sumber daya pada proses ini, mungkin cakupannya terlalu terbatas, atau sumber daya pada "bagian belakang" seorang penerjemah tanpa menjadi terlalu teoretis, itulah sebabnya saya diposting di sini.


1
Ada banyak sumber daya seperti ini. Perhatikan bahwa garis antara kompiler dan interpreter lebih kabur dari yang Anda kira; kompiler C # 4.0 mendukung pemrograman dinamis, seperti halnya sejumlah kompiler lainnya.
Robert Harvey

@RobertHarvey Ya, yang saya minta adalah sumber daya untuk membuat run time / interpreter / mesin virtual saya sendiri. Penerjemah .Net terlalu rumit bagi saya untuk menjadikan basis dari!
Austin Henley


1
Dan lihat pertanyaan SO ini , ada beberapa komentar dengan referensi ke pertanyaan lain yang cukup menarik ...
yannis

Jawaban:


4

Pertama-tama pelajari tentang menerapkan juru bahasa. Saya merekomendasikan PLAI (Bahasa Pemrograman: Aplikasi dan Interpretasi) . Itu sampai ke daging interpretasi dengan cepat tanpa tinggal terlalu lama pada sintaks.

Untuk bahasa Anda, Anda akan dapat menggunakan kembali front-end kompiler (parser, kebanyakan) dan run-time library (GC, struktur data, operasi primitif, dll).

Tentu saja, Anda juga dapat mengimplementasikan bahasa dinamis dengan kompiler yang menghasilkan kode yang memanipulasi (sebagian) struktur data yang sama yang akan Anda gunakan dalam juru bahasa. Misalnya, dalam juru bahasa Anda bisa mengimplementasikan variabel global sebagai tabel hash yang diindeks-string. Di kompiler, Anda akan mengkompilasi referensi variabel global ke dalam kode yang melakukan pencarian menggunakan tabel yang sama. Sebaliknya, Anda bisa mengkompilasi variabel leksikal menjadi representasi yang lebih efisien (argumen "asli" dan referensi struktur penutupan).


5

Jika Anda ingin mempelajari dasar-dasar penerapan juru bahasa untuk bahasa yang dinamis, saya tidak bisa membayangkan tempat yang lebih baik untuk memulai daripada asal-usul bahasa pemrograman pertama yang ditafsirkan secara dinamis: Lisp.

Dalam makalah aslinya tahun 1960 , John McCarthy mendefinisikan 5 fungsi primitif yang diperlukan untuk seorang Lisp. Tentu saja, McCarthy hanya bermaksud makalahnya tentang Lisp sebagai latihan akademis; itu adalah seorang mahasiswa pascasarjana yang terlibat evaldalam perakitan dan menciptakan juru bahasa Lisp pertama. Paul Graham mengidentifikasi tujuh primitif : kutipan, atom, persamaan, kontra, mobil, cdr, dan kond.

Masalahnya, Anda benar-benar dapat mengimplementasikan Lisp dalam bahasa apa pun; begitu Anda menerapkan eval, mudah untuk membuat REPL, dan Anda memiliki juru bahasa interaktif . Orang-orang sudah bosan atau cukup ingin tahu untuk mengimplementasikan Lisps dalam bahasa C, Java, Ruby, Python, dan banyak lainnya. Dan tidak selalu dengan sengaja; Penting untuk diingat Aturan Kesepuluh Greenspun :

Setiap program C atau Fortran yang cukup rumit berisi implementasi ad hoc, dispesifikasikan secara informal, ditanggulangi, lambat dari separuh Common Lisp.

Saya tidak mengatakan tujuan akhir Anda harus menjadi implementasi Lisp; tetapi homoiconicity memiliki manfaat ketika belajar menerapkan bahasa yang dinamis; mengapa berurusan dengan masalah sintaks ketika Anda bisa belajar pada bahasa di mana sintaksis idiom identik dengan AST bahasa yang menggunakan lexer / parser?

Bagaimanapun ... hanya saran. Tetapi dengan alasan yang kuat bahwa sebagian besar bahasa pemrograman yang bagus sejak C memiliki setidaknya sedikit sifat Lisp.


1
Saya berharap saya bisa menerima dua jawaban. Terima kasih, saya pikir saya benar-benar akan menerapkan juru bahasa Lisp. Sangat mudah untuk menguraikan, memiliki banyak dokumentasi dan kode yang ada, dan harus memberi saya dasar untuk bekerja dengannya. Sayangnya saya mengambil kelas sarjana yang menggunakan Skema dan itu membuat saya mencabut rambut saya;)
Austin Henley

1
Saya sekarang tergoda untuk mengkompilasi bahasa saya ke dalam dialek Lisp saya sendiri!
Austin Henley


0

Saya telah meletakkan ini (~ 600 baris C #) di domain publik, yang mendukung kutipan / daftar / terapkan / eval / test / dll, dan memungkinkan untuk mengkustomisasi sintaks seperti Lisp dan / atau builtin semantik dengan mudah:

https://repl.it/CdjV/3

Misalnya:

        var factorial = (Lambda)language.
            Evaluate
            (@"
                ( => ( n ) (
                        ? ( != n 0 )
                        ( * n ( this ( - n 1 ) ) )
                        1
                    )
                )
            ");

        var sw = new System.Diagnostics.Stopwatch();
        var n = 12;
        var r = 0;
        int k;
        sw.Start();
        for (k = 0; k < 10000; k++)
        {
            r = (int)factorial.Invoke(null, n);
        }
        sw.Stop();
        Console.WriteLine("{0}! = {1}", n, r);
        Console.WriteLine();
        Console.WriteLine("in {0} ms (for {1} times)", sw.ElapsedMilliseconds, k.ToString("0,0"));

'HTH,


0

Dengan asumsi Anda tahu sedikit Skema (misalnya telah membaca SICP ) atau Lisp, saya merekomendasikan buku Lisp In Small Pieces karya Queinnec . Ini menjelaskan beberapa varian interpreter & kompiler mirip Lisp (termasuk ke bytecode atau ke C).

Juga, baca Scott's Programming Language Pragmatics , Buku Naga terbaru , buku pegangan GC , Jenis - jenis Pierce & bahasa pemrograman .

Saya mencari informasi tentang cara beralih dari kompiler ke juru bahasa.

Kemudian, evaluasi parsial (& proyeksi Futamura) dan gaya kelanjutan dapat menjadi relevan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.