Berdasarkan komentar oleh George Edison untuk pertanyaan ini , tulislah juru penterjemah mandiri terkecil.
- Anda dapat menggunakan bahasa yang Anda pilih.
- Bahasa kosong tidak masuk hitungan. Panjang program Anda harus minimal dua karakter.
- Program ini tidak perlu menginterpretasikan seluruh bahasa, hanya subset lengkap fitur bahasa Turing (yang berisi penerjemah).
- Quines tidak masuk hitungan.
- Jangan gunakan
eval
fungsi bawaan bahasa Anda atau yang setara. Sama berlaku untukapply
, dll.
code-golf
interpreter
Hoa Long Tam
sumber
sumber
/usr/bin/cat
) bagaimana dengan Turing-kelengkapan?sexp
parser.Jawaban:
CI - 260
320 → 260: Dorong pemetaan karakter-ke-instruksi sederhana, lalu lipat. Ini membagi dua ukuran kode per kas (ada 18 kas), tetapi biaya 30 karakter untuk melakukan lipat.
Ini adalah salah satu dari bahasa saya yang dikonstruksi, (juru bahasa dasar yang dihosting di Gist ). Ini unik karena bahasa tersebut mengubah fragmen kode. Artinya, string instruksi dalam bahasa berbasis stack ini digunakan untuk efek yang sama dengan struktur data atau penutupan dalam bahasa lain:
Penerjemah membangun fragmen kode dari seluruh program sebelum menjalankannya, sehingga ia juga dapat dianggap sebagai kompiler. Karena itu, penumpukan juru bahasa tidak menghasilkan overhead run-time eksponensial.
Juru bahasa memperoleh semua operatornya secara langsung dari juru bahasa induk. Namun, ia melakukan parsing dengan sendirinya, sehingga sebagian besar kode hanyalah urutan yang menerjemahkan karakter ke dalam literal kode masing-masing. Ini tidak sama dengan menggunakan
eval
, tetapi ia mengungkapkan betapa tergantungnya implementasi bahasa pemrograman pada semantik bahasa host / arsitekturnya.Referensi bahasa:
Dapatkan penerjemahnya di sini
Blok
(
...)
Buat "blok", yang secara efektif adalah daftar instruksi tanpa konteks. Secara internal, itu bahkan bisa menjadi kode mesin.
blok
$
Panggil satu blok. Callee diberikan tumpukan global, yang termasuk blok dipanggil.
nilai
^
Angkat nilai. Yaitu, ubah menjadi blok yang mendorong nilai itu.
Contoh :
block1 block2
&
Bergabunglah dua blok, membentuk satu yang menjalankan keduanya secara berurutan.
Contoh :
Manipulasi tumpukan
n
c
Salin nilai n stack.
Contoh :
n
p
Ambil nilai n stack (lepaskan, dan bawa ke depan).
Contoh :
n
d
Jatuhkan n nilai dari tumpukan.
0d
adalah no-op.Contoh :
Operator relasional
ab (on_true) (on_false)
=
Tes jika a sama dengan b. Konsumsi semua kecuali argumen pertama, dan panggil on_true atau on_false. Jika satu argumen nol dan yang lainnya adalah tipe lainnya, hasilnya akan salah. Kalau tidak, a dan b harus bilangan bulat.
Contoh :
ab (on_true) (on_false)
<
Tes jika a kurang dari b. a dan b harus berupa bilangan bulat.
Contoh :
ab (on_true) (on_false)
>
Uji apakah a lebih besar dari b. a dan b harus berupa bilangan bulat.
Contoh :
a lo hi (on_true) (on_false)
~
Tes jika lo <= a <= hai. a, lo, dan hai harus bilangan bulat.
Contoh :
I / O
c
.
Masukkan karakter c (mengkonsumsinya dari tumpukan).
,
Dapatkan karakter dan dorong ke tumpukan. Jika akhir file telah tercapai, -1 didorong.
c
!
Tidak mendapatkan karakter. Sama seperti ungetc di C, hanya satu pushback yang diizinkan.
Literal integer
'c
Dorong karakter c.
[0-9] +
Dorong bilangan bulat desimal.
Hitung
+
-
ab
*
Tambahkan / kurangi / gandakan dua angka.
Contoh :
ab
/
ab
%
Pembagian dan modulus. Tidak seperti di C, putaran ini menuju infinity negatif.
Lain-lain
#
komentar kodeThe
#
karakter komentar segala sesuatu ke akhir baris.)
Digunakan untuk mengakhiri blok. Dapat digunakan untuk mengakhiri seluruh program juga.
Semua karakter lain diabaikan.
sumber
Binary Lambda Calculus, 232 bits (29 bytes)
0101000110100000000101011000000000011110000101111110011110000101110011110000001111000010110110111001111100001111100001011110100111010010110011100001101100001011111000011111000011100110111101111100111101110110000110010001101000011010
Lihat http://en.wikipedia.org/wiki/Binary_lambda_calculus#Lambda_encoding untuk detail
sumber
Saya tidak dapat mengambil kredit untuk yang ini , tetapi saya pikir saya akan membagikan yang menakjubkan ini:
Brainf *** (423)
sumber
BlockScript - 535
BlockScript adalah setumpuk spaghetti sepele- bahasa yang saya buat khusus untuk tantangan ini. Penerjemah dasar adalah blockscript.c .
Program sampel (mencetak 15 angka Fibonacci pertama):
Interpreter membaca kode sumber dan input program dari input standar, dalam urutan itu. Ini berarti bahwa untuk menjalankan juru bahasa dalam juru bahasa dalam sebuah juru bahasa, cukup salin dan tempel:
Seperti film Inception , Anda tidak dapat mencapai lebih dari tiga level. Ini bukan masalah waktu, tetapi ruang. BlockScript sangat banyak kebocoran memori, dan ini ada hubungannya dengan bagaimana bahasa itu sendiri dirancang.
Referensi bahasa:
Dapatkan penerjemahnya di sini
Dalam BlockScript, "tumpukan" bukan array yang ditimpa oleh operasi selanjutnya seperti Anda mungkin terbiasa. Ini sebenarnya diimplementasikan sebagai daftar tertaut yang tidak dapat diubah, dan tumpukan tetap ada selama durasi program. Juga, tidak ada operator (kecuali
@
) yang menghapus nilai dari stack. Namun, modifikasi tumpukan hanya mempengaruhi blok tempat terjadinya.Seleksi nilai
a
melaluiz
Ambil item 0-25 dari tumpukan, dan dorong ke tumpukan.
a
mengacu pada kepala, atau item yang paling baru didorong, dari tumpukan.A
melaluiZ
Ambil item 0-25 dari frame saat ini, dan dorong ke stack.
[
Buka "bingkai" untuk memilih item dari referensi tumpukan (lihat di bawah) di kepala tumpukan.
[
tidak memerlukan pencocokan]
, tetapi bingkai dibatasi secara leksikal. Dalam BlockScript, "lingkup" ditentukan oleh tanda kurung ({
...}
) yang membentuk blok. Dengan demikian, membuka bingkai di dalam blok tidak akan berpengaruh pada kode di luar blok.]
Tutup frame saat ini, kembali ke frame sebelumnya (jika ada).
Blok
{
...}
Buat "blok", dan dorong ke tumpukan. Di dalam blok, tumpukan akan mulai seperti sebelum blok, kecuali tumpukan penelepon akan didorong di atas. Tumpukan gigih dan tidak berubah dalam BlockScript, jadi blok adalah penutup. Ungkapan tersebut
{[
berarti membuka blok, lalu membuka bingkai untuk mulai memilih argumen (menggunakanA
melaluiZ
). Nilai kembali blok adalah kepala tumpukan saat}
tercapai.Contoh:
Ini mencetak
123BCD123DCB123BCD123DCB…
. Huruf kecil mengacu pada nilai stack, sedangkan huruf besar merujuk pada argumen (karena frame diatur ke tumpukan pemanggil).A!
mengambil kepala penelepon (yang dijamin menjadi blok yang dipanggil) dan memanggilnya. Jika Anda bertanya-tanya mengapa pembalikan terjadiBCD
setiap saat, itu karenaB. C. D.
mendorong argumen tersebut dalam urutan terbalik tepat sebelum blokir memanggil dirinya sendiri.!
Panggil satu blok. Dorong nilai kembali ke tumpukan.
Referensi tumpukan
&
Buat referensi tumpukan, dan dorong ke tumpukan. Anggap ini sebagai "super-kontra", karena secara efektif mengeluarkan setiap item di stack dan membentuk "tuple" darinya. Idiom
&[
berarti bahwa apa puna
,b
,c
disebut sebelum sekarang dapat diakses denganA
,B
,C
(untuk sisa blok atau sampai]
ditemui).Sebagian karena
&
menangkap lebih banyak nilai daripada biasanya, BlockScript membocorkan memori dengan desain.@
Beralih ke tumpukan yang ditunjuk oleh referensi tumpukan
a
. Operator ini agak aneh, tetapi penerjemah mandiri BlockScript menggunakannya beberapa kali untuk menghindari keharusan mendorong argumen yang sama dua kali. Efek dari@
(atau operasi stack, dalam hal ini) terbatas pada blok di mana ia dipanggil. Selain itu, frame tidak terpengaruh oleh@
, sehingga frame dapat digunakan untuk mengambil nilai yang Anda butuhkan setelah beralih tumpukan.Ekspresi bersyarat
?
<Benar>:
<on false>Ekspresi bersyarat, sama seperti operator ternary dalam C. Artinya, jika
a
"benar" (yaitu, tidak sama dengan nol bilangan bulat), maka lakukan <pada true> , jika tidak lakukan <pada false> .I / O
Catatan: Input dan output dilakukan dalam UTF-8. "Karakter" adalah bilangan bulat yang sesuai dengan indeks Unicode.
,
Dapatkan karakter input berikutnya, dan dorong ke tumpukan. Jika akhir input tercapai, tekan -1.
.
Keluarkan karakter di kepala tumpukan.
Literal integer / karakter
Catatan: Integer dan karakter adalah hal yang sama di BlockScript.
'c
Dorong karakter c.
[0-9] +
Dorong bilangan bulat desimal.
Hitung
Operator ini hanya bekerja pada nilai integer.
+
Computeb
+a
(mendorong hasilnya, tetapi tidak membuang salah satu nilai).-
Hitungb
-a
.*
Hitungb
*a
./
Hitungb
/a
(pembagian bilangan bulat; putaran menuju infinity negatif).%
Hitungb
%a
(bilangan bulat modulus; putaran ke arah infinity negatif).Operator relasional
Operator ini hanya bekerja pada nilai integer.
<
Jikab
kurang daria
, tekan 1, jika tidak tekan 0.>
=
Lain-lain
#
Komentar ke akhir baris;
sumber
Zozotez LISP : 414
linefeeds yang ditambahkan untuk mendapatkan blok yang bagus tidak diperlukan dan tidak dihitung.
Secara teori seharusnya bisa menjalankan sendiri, tetapi karena penerjemah asli adalah biner BrainFuck dan itu sendiri penerjemah saya hanya bisa menguji setiap bagian. Ketika diberikan sendiri dan ekspresi sederhana,
(p p)
saya pikir itu membutuhkan lebih banyak waktu daripada 40 menit saya telah menunggu sejauh ini dan saya menggunakan puasa sayajitbf
untuk menjalankannya yang (salah) menggunakan Perl Inline-C untuk menjalankan kode C dengan cepat.Tidak mungkin untuk mengimplementasikan seluruh Zozotez di Zozotez karena tidak memiliki cara untuk bermutasi kontra dan
:
(setq / define) memerlukan itu untuk memperbarui binding. Saya juga tidak menerapkan argumen begin / progn or & rest, makro dan argumen pencetakan khusus karena saya tidak menggunakannya dalam juru bahasa. Saya memang memasukkanp
(mencetak) meskipun saya tidak menggunakannya sehingga program perlu mencetak kalkulasi mereka secara eksplisit seperti juru bahasa asli.Yang ungolfed sama:
sumber
CHIQRSX9 + (mungkin tidak bersaing), 2 byte
Tidak ada cara untuk menulis interpreter interpretasi mandiri dalam bahasa berbasis HQ9 + ini tanpa menggunakan
I
, yang menjalankan interpreter internal yang memproses STDIN.sumber
eval
, yang untuk ekspresi, bukan program.X
seharusnya membuat bahasa Turing-complete (dengan demikian dapat menghitung bilangan prima) dengan cara yang bergantung pada implementasi.X
perintah penerjemah Perl secara acak mengganggu program dan mengeksekusinya, yang berarti bahwa seseorang tidak dapat menggunakan selain perintah untuk secara perhitungan menghitung bilangan prima. Bisakah Anda memberi saya contoh penerjemah yang memungkinkan Anda menggunakanX
dengan cara yang Anda tentukan?Concurrent Filesystem Befunge 98 - 53 \ 18 bytes (hampir pasti curang)
Interpreter 53 byte penuh tanpa batasan (walaupun saya belum menguji interaksi waktu yang rumit yang melibatkan pemisahan IP dan pembungkus):
Membaca input dari file bernama
a
dan menjalankannya. Itu tidak ditentukan dalam aturan bahwa kita tidak dapat menggunakan kode modifikasi diri.Interpreter 18 byte yang tidak memungkinkan pembungkus (IP bergerak dari satu sisi kode dan mulai dari sisi yang berlawanan):
sumber