Perkembangan bahasa skrip saya yang diketik secara statis Umka memasuki tahap ketika diperlukan untuk menguji kemampuan bahasa menggunakan contoh yang lebih kompleks daripada skrip dalam beberapa lusin baris. Untuk ini, saya memutuskan untuk menerapkan penerjemah Lisp dalam bahasa saya . Saya terinspirasi oleh eksperimen pedagogis oleh Rob Pike, salah satu pencipta bahasa Go. Pike baru-baru ini menerbitkan penerjemah Lisp kecil di Go . Saya sangat terkesan dengan pernyataan Pike bahwa deskripsi juru bahasa ada di satu halaman 13 dari manual Lisp 1.5 kuno .... Mengingat afinitas sintaksis Umka dan Go, sulit untuk menahan godaan untuk membangun penerjemah seperti itu di Umka, tidak dengan benar-benar mentransfer kode Pike, tetapi sepenuhnya dari awal. Saya berharap para penikmat Lisp dan bahasa fungsional akan memaafkan saya rasa takjub naif berhubungan dengan keindahan.
Bagi yang belum tahu, Lisp bisa dianggap hampir shock. Di manakah batas antara kode dan data? Dimana loopnya? Dimana tumpukannya? Satu-satunya struktur data adalah pohon. Itu juga bisa mewakili daftar. Ini juga menjadi pohon sintaks abstrak saat program diuraikan. Ini juga menggantikan tumpukan saat mengevaluasi ekspresi. Setiap pohon dapat dicoba untuk dieksekusi sebagai kode atau digunakan sebagai data. Alih-alih loop - rekursi. Bahkan tidak ada aritmatika dalam inti bahasa tersebut. Namun, ini adalah bahasa lengkap Turing yang dapat diperluas tanpa batas dan ditaburi gula sintaksis.
Mendefinisikan juru bahasa Lisp minimal membutuhkan waktu kurang dari satu halaman. Secara umum, tentu saja: ia menggunakan fungsi yang ditentukan pada beberapa halaman sebelumnya. Pencipta Lisp, John McCarthy tampaknya telah berusaha keras untuk melampaui dirinya sendiri dalam keringkasan dan akhirnya menerbitkan manual mikro Lisp yang berisi definisi bahasa bersama dengan sumber penerjemah - total dua halaman majalah. Benar, dia menambahkan ke judul: " Bukan kebenaran seluruhnya ".
Inti dari bahasa (di sini kita berbicara tentang dialek tertua dan paling sederhana) membutuhkan lima fungsi dasar, empat kata kunci dan dua konstanta yang tidak dapat diekspresikan melalui bahasa itu sendiri.
Konstruksi bahasa dasar bagi mereka yang tidak terbiasa dengannya
(car x)- menyorot bagian atas daftarx(cdr x)—x(cons x y)—xy(atom x)—x(eq x y)—xy(cond (a x) (b y))—xyab(quote x)—x,((lambda (x) a) y)—a,xy((label ff (lambda (x) a)) y)—fft—nil—
, . , , , 6:
((label fac (lambda (n) (cond ((eq n 0) 1) ((quote t) (mul n (fac (sub n 1))))))) 6)
Lisp, . Lisp 1.5 13 , . . , REPL . , , , label defn, , . Lisp .
Karena seluruh penafsir penuh dengan rekursi dan pemrosesan pohon, ini berfungsi sebagai tes yang sangat baik untuk banyak fitur bahasa Umka, dari menumpuk hingga pengumpulan sampah. Saya pikir Umka melakukannya dengan baik dalam ujian. Kami harus memperbaiki hanya dua atau tiga bug kecil yang terkait dengan ekspor nama dan deklarasi tipe lanjutan. Seluruh kode penerjemah kurang dari 400 baris.
Bagi mereka yang ingin bermain-main dengan penerjemah saya dan meneruskan inspirasi dari Rob Pike melalui relai, saya sarankan untuk mengambil folder dengan contoh dari cabang master , dan bukan dari rilis terbaru .