Clem adalah bahasa pemrograman berbasis stack minimal yang menampilkan fungsi kelas satu. Tujuan Anda adalah menulis penerjemah untuk bahasa Clem. Itu harus benar menjalankan semua contoh termasuk dalam implementasi referensi, yang tersedia di sini .
- Seperti biasa, celah standar berlaku.
- Entri terkecil dengan jumlah byte menang.
Bahasa Clem
Clem adalah bahasa pemrograman berbasis stack dengan fungsi kelas satu. Cara terbaik untuk mempelajari Clem adalah dengan menjalankan clem
interpreter tanpa argumen. Ini akan mulai dalam mode interaktif, memungkinkan Anda untuk bermain dengan perintah yang tersedia. Untuk menjalankan program contoh, ketik di clem example.clm
mana contoh adalah nama program. Tutorial singkat ini seharusnya sudah cukup untuk membantu Anda memulai.
Ada dua kelas fungsi utama. Fungsi atomik dan fungsi majemuk. Fungsi senyawa adalah daftar yang terdiri dari fungsi senyawa lain dan fungsi atom. Perhatikan bahwa fungsi gabungan tidak dapat mengandung dirinya sendiri.
Fungsi Atom
Tipe pertama dari fungsi atom adalah konstanta . Sebuah konstan hanyalah sebuah nilai integer. Misalnya, -10. Ketika penerjemah menemukan konstanta , itu mendorongnya ke tumpukan. Jalankan clem
sekarang. Ketik -10
pada prompt. Anda harus melihat
> -10
001: (-10)
>
Nilai tersebut 001
menggambarkan posisi fungsi dalam tumpukan dan (-10)
merupakan konstanta yang baru saja Anda masukkan. Sekarang masukkan +11
saat diminta. Anda harus melihat
> +11
002: (-10)
001: (11)
>
Perhatikan bahwa (-10)
telah pindah ke posisi kedua di tumpukan dan (11)
sekarang menempati posisi pertama. Ini adalah sifat tumpukan! Anda akan melihat bahwa -
itu juga perintah pengurangan. Setiap kali -
atau +
mendahului nomor, mereka menunjukkan tanda nomor itu dan bukan perintah yang sesuai. Semua fungsi atom lainnya adalah perintah . Total ada 14:
@ Rotate the top three functions on the stack
# Pop the function on top of the stack and push it twice
$ Swap the top two functions on top of the stack
% Pop the function on top of the stack and throw it away
/ Pop a compound function. Split off the first function, push what's left,
then push the first function.
. Pop two functions, concatenate them and push the result
+ Pop a function. If its a constant then increment it. Push it
- Pop a function. If its a constant then decrement it. Push it
< Get a character from STDIN and push it to the stack. Pushes -1 on EOF.
> Pop a function and print its ASCII character if its a constant
c Pop a function and print its value if its a constant
w Pop a function from the stack. Peek at the top of the stack. While it is
a non-zero constant, execute the function.
Mengetik perintah saat diminta akan menjalankan perintah. Ketik #
saat diminta (perintah rangkap). Anda harus melihat
> #
003: (-10)
002: (11)
001: (11)
>
Perhatikan bahwa (11) telah digandakan. Sekarang ketikkan %
pada prompt (perintah drop). Anda harus melihat
> %
002: (-10)
001: (11)
>
Untuk mendorong perintah ke tumpukan, cukup lampirkan dalam tanda kurung. Ketik (-)
pada prompt. Ini akan mendorong operator pengurangan ke tumpukan. Anda harus melihat
> (-)
003: (-10)
002: (11)
001: (-)
>
Fungsi gabungan
Anda juga dapat menyertakan beberapa fungsi atom dalam tanda kurung untuk membentuk fungsi majemuk. Ketika Anda memasukkan fungsi gabungan saat diminta, itu didorong ke tumpukan. Ketik ($+$)
pada prompt. Anda harus melihat
> ($+$)
004: (-10)
003: (11)
002: (-)
001: ($ + $)
>
Secara teknis, semua yang ada di stack adalah fungsi majemuk. Namun, beberapa fungsi senyawa pada stack terdiri dari fungsi atom tunggal (dalam hal ini, kami akan menganggapnya sebagai fungsi atom demi kenyamanan). Saat memanipulasi fungsi majemuk pada stack, .
perintah (concatenation) seringkali berguna. Ketikkan .
sekarang. Anda harus melihat
> .
003: (-10)
002: (11)
001: (- $ + $)
>
Perhatikan bahwa fungsi pertama dan kedua pada stack digabungkan, dan bahwa fungsi kedua pada stack datang pertama dalam daftar yang dihasilkan. Untuk menjalankan fungsi yang ada di stack (apakah itu atomik atau gabungan), kita harus mengeluarkan w
perintah (while). The w
perintah akan muncul fungsi pertama pada stack dan jalankan berulang kali selama fungsi kedua pada stack adalah non-nol konstan. Cobalah untuk memprediksi apa yang akan terjadi jika kita mengetik w
. Sekarang, ketik w
. Anda harus melihat
> w
002: (1)
001: (0)
>
Itukah yang kamu harapkan? Dua angka yang duduk di atas tumpukan ditambahkan dan jumlahnya tetap. Ayo kita coba lagi. Pertama kita akan menjatuhkan nol dan mendorong 10 dengan mengetik %10
. Anda harus melihat
> %10
002: (1)
001: (10)
>
Sekarang kita akan mengetikkan seluruh fungsi dalam satu tembakan, tetapi kita akan menambahkan ekstra %
di akhir untuk menghilangkan nol. Ketik (-$+$)w%
pada prompt. Anda harus melihat
> (-$+$)w%
001: (11)
>
(Perhatikan algoritma ini hanya berfungsi jika konstanta pertama pada stack positif).
String
String juga ada. Mereka sebagian besar gula sintaksis, tetapi bisa sangat berguna. Ketika penerjemah menemukan sebuah string, itu mendorong setiap karakter dari yang terakhir ke yang pertama ke tumpukan. Ketik %
untuk menjatuhkan 11 dari contoh sebelumnya. Sekarang, ketik 0 10 "Hi!"
prompt. The 0
akan memasukkan terminator NULL dan 10
akan menyisipkan karakter baru-line. Anda harus melihat
> 0 10 "Hi!"
005: (0)
004: (10)
003: (33)
002: (105)
001: (72)
>
Ketik (>)w
untuk mencetak karakter dari tumpukan hingga kami menemukan terminator NULL. Anda harus melihat
> (>)w
Hi!
001: (0)
>
Kesimpulan
Semoga ini cukup untuk membantu Anda memulai dengan juru bahasa. Desain bahasa harus relatif lurus ke depan. Beri tahu saya jika ada sesuatu yang sangat tidak jelas :) Beberapa hal sengaja dibiarkan kabur: nilai harus ditandatangani dan setidaknya 16 bit, tumpukan harus cukup besar untuk menjalankan semua program referensi, dll. Banyak detail belum diukir di sini karena spesifikasi bahasa lengkap akan sangat besar untuk dikirim (dan saya belum menulis satu pun: P). Jika ragu, meniru implementasi referensi.