Anda harus menulis penerjemah untuk bahasa keren bernama Chicken !
Anda harus membaca program Chicken dari file, input standar, argumen program atau fungsi, atau apa pun yang paling nyaman untuk bahasa Anda, serta input ke program.
Anda harus mencetak atau mengembalikan hasil interpretasi program sesuai dengan spesifikasi bahasa Chicken.
Keterangan lebih lanjut tentang bahasa ini .
Ikhtisar Program Ayam
Chicken beroperasi pada tumpukan tunggal, yang menyusun seluruh model memori. Saat instruksi dijalankan, program akan mendorong dan mengeluarkan nilai dari stack, tetapi ada juga instruksi yang memungkinkan program untuk memodifikasi bagian lain dari stack sesuai keinginan.
Ada tiga segmen dalam tumpukan:
- Register, pada indeks 0 dan 1. Indeks 0 adalah referensi ke stack itu sendiri, dan indeks 1 adalah referensi ke input pengguna. Paling banyak digunakan untuk instruksi 6 (lihat di bawah).
- Kode yang dimuat: untuk setiap baris kode ada sel di segmen ini yang berisi jumlah "ayam" di baris. Ini diisi dengan 0 (opcode untuk mengakhiri program) di akhir.
- Tumpukan program aktual, di mana nilai didorong / muncul saat program berjalan. Perhatikan bahwa segmen tidak terisolasi, yang berarti dimungkinkan untuk membuat kode modifikasi sendiri atau mengeksekusi kode dari segmen ruang stack ini.
The Chicken ISA
Kumpulan instruksi Chicken didasarkan pada berapa kali kata "chicken" muncul di setiap baris program. Baris kosong mengakhiri program dan mencetak nilai teratas dalam tumpukan.
Kumpulan instruksi Ayam, dengan jumlah "ayam" per baris:
- Dorong string literal "ayam" ke tumpukan
- Tambahkan dua nilai tumpukan teratas sebagai angka alami dan dorong hasilnya.
- Kurangi dua nilai teratas sebagai bilangan asli dan dorong hasilnya.
- Gandakan dua nilai teratas sebagai bilangan asli dan dorong hasilnya.
- Bandingkan dua nilai teratas untuk kesetaraan, tekan 1 jika sama dan 0 sebaliknya.
- Lihatlah instruksi selanjutnya untuk menentukan sumber mana yang akan memuat: 0 beban dari tumpukan, 1 beban dari input pengguna. Atas tumpukan poin ke alamat / indeks untuk memuat dari sumber yang diberikan; muat nilai itu dan dorong ke tumpukan. Karena ini adalah instruksi lebar ganda, penunjuk instruksi melewatkan instruksi yang digunakan untuk menentukan sumber.
- Atas tumpukan poin ke alamat / indeks untuk menyimpan. Nilai di bawah ini yang akan muncul dan disimpan dalam tumpukan pada indeks yang diberikan.
- Top of stack adalah offset relatif untuk melompat ke. Jika nilai di bawah ini benar, maka program melompat dengan offset.
- Menafsirkan bagian atas tumpukan sebagai ascii dan mendorong karakter yang sesuai.
- (10 + N) Mendorong angka literal n-10 ke tumpukan.
Contoh
Asumsikan programnya adalah:
chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken chicken
chicken chicken chicken chicken chicken chicken
(an empty line)
(Program kucing. Perhatikan bahwa garis kosong diperlukan karena garis sebelumnya memiliki 6 "ayam".)
Masukan diberikan ke program Chicken
Chicken
Keluaran
Chicken
Implementasi referensi Chicken.js .
Deteksi kesalahan
Penerjemah harus meninggalkan kesalahan dan mengakhiri ketika kata apa pun yang bukan "ayam" ada di sumbernya.
Semoga berhasil!
sumber
Jawaban:
Ruby, 335 byte
Mengambil nama file input sebagai argumen baris perintah dan mengambil input pengguna (untuk instruksi # 6) dari STDIN.
Karena Ruby "truthy" (semuanya kecuali
false
dannil
) berbeda dari Javascript "truthy" (Ruby truthy plus0
, string kosong, dll.), Mungkin ada beberapa kasus tepi di mana program yang berfungsi dengan baik pada penerjemah JS gagal pada yang satu ini karena instruksi # 8, seperti jika""
ada di stack. Saya sudah memperbaiki kasus terbesar, yang palsu0
.Bekerja dengan program pengujian dan program Hello World di situs web Chicken.
Penjelasan
Penerjemah segera memulai dengan menjalankan kecocokan regex
/^(chicken|\s)*$/m
terhadap seluruh file ($<.read
), yang memastikan file tersebut tidak berisi apa pun kecualichicken
spasi. Di Ruby, operator ini mengembalikan indeks untuk pertandingan, ataunil
jika tidak ditemukan.Trik penghematan dua byte digunakan di sini: alih-alih mencocokkan secara langsung
chicken
, operator substitusi string#{}
digunakan sebagai gantinya untuk juga menetapkan string itu ke variabel untuk nanti (menyimpan 1 byte), dan ketika menyimpan konten file ke variabel untuk diproses , itu menambahkan dua baris baru untuk memungkinkanlines
fungsi nanti menambahkan secara alami tambahan0
ke akhir set instruksi. (Dua diperlukan karena mengabaikan trailing newline, yang diperlukan untuk program Chicken.)Kesalahan yang digunakan adalah
NoMethodError: undefined method '+@' for nil:NilClass
, yang dilakukan dengan membungkus pertandingan regex di parens dan menempatkan+
di depan. Jika file cocok dengan pola, Anda dapatkan+0
, yang mengevaluasi0
dan menghasilkan secara normal.Selanjutnya, tumpukan dirakit. Daftar awal harus dibuat sebelum referensi mandiri ke stack dapat ditetapkan, sehingga pengganti digunakan dan kemudian diganti. Pointer instruksi diatur ke
1
bukan2
karena operator pasca kenaikan tidak ada di Ruby.Akhirnya, ia menggunakan trik lambda dari @BassdropCumberwubwubwub untuk menentukan apa yang harus mendorong tumpukan berikutnya. Jika suatu operasi tidak mendorong apa pun ke stack, interpreter hanya mengeluarkan nilai tambahan sehingga stack tetap sama. (Ini menghemat byte daripada menambahkan operasi push ke setiap lambda tunggal.)
Kode tidak dikunci:
sumber
Javascript ES6, 398 byte
Sejauh ini golf terpanjang yang pernah saya lakukan, saya yakin ini bisa diperbaiki tetapi otak saya tidak mengenali apa pun selain
chicken
saat ini.Saya akan mengedit penjelasan ketika otak saya mulai berfungsi kembali. Ini versi yang sedikit tidak diubah untuk saat ini.
Menghasilkan nilai falsey (0) untuk semua yang tidak
chicken
Coba di sini
sumber
if(!/^(chicken\s?)+$/.test(a))throw'There are any words except "chicken".';
tepat pada awal penerjemah Anda.stderr
atau keluar dari program dengan kode bukan nol. Sesuatu yang menunjukkan bahwa ada sesuatu yang tidak benar. Di Javascript, Anda bisa melempar pengecualian, mengembalikan objek Galat, menampilkan lansiran, menulis ke konsol menggunakanconsole.erro()
atau yang serupa.