BlockScript - 535
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
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):
{[B?B10/A!B10%d&:0}
{[B0<?'-.0B-A!:{B?Bh!{[B?B[A]A!B[B]'0+.:}!:'0.}!10.}
{[B?Dd!DC+B1-CecA!:}
0 1 15d!
;
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:
# Level 1
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
# Level 2
{[B':=?0:B';=?0:B'}=?0:B'{=?,A!,A!d1c&:B'?=?,A!,A!2e&:B''=?,,A!d3c&:B{[B'0<?0:B
'9>?0:1}!?B'0-{[,g!?c'0-B10*d+A!:Bd]A!d3c&}!:B'#=?{[,10=?,]A!:A!}!:,A!Bb&}{[AC[
B]DB?[AB{[Bh&hbhn!}{[B[AB]C?1-eA!:b}&[C1=?E[C]FHc&B!:C2=?{G?D:E[C}!FHcI!:C3=?E[
C]B!:C'!=?G[ABC]Hc&dbh&D?b@I!B!:b@I!:C'&=?HB!:C'@=?FGDI!:C'[=?GF&HDI!:C']=?F[A]
HDI!:C',=?,B!:C'.=?G.FHDI!:C'a'z{[DC<?0:DB>?0:1}!?Ce-HA!B!:C'A'Ze!?F[B]Cg-dA!B!
:{C'+=?{[CB+}:C'-=?{[CB-}:C'*=?{[CB*}:C'/=?{[CB/}:C'%=?{[CB%}:C'<=?{[CB<}:C'>=?
{[CB>}:C'==?{[CB=}:0}!?H[A][B]Ge!B!:FHDI!:c},c!0ac&0&0&0bho!;
# Level 3
{[B?B10/A!B10%d&:0}
{[B0<?'-.0B-A!:{B?Bh!{[B?B[A]A!B[B]'0+.:}!:'0.}!10.}
{[B?Dd!DC+B1-CecA!:}
0 1 15d!
;
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
melalui z
Ambil item 0-25 dari tumpukan, dan dorong ke tumpukan. a
mengacu pada kepala, atau item yang paling baru didorong, dari tumpukan.
A
melalui Z
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 (menggunakan A
melalui Z
). Nilai kembali blok adalah kepala tumpukan saat }
tercapai.
Contoh:
'3 '2 '1 {[ b. d. f. B. C. D. A! } 'D 'C 'B d!;
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 terjadi BCD
setiap saat, itu karena B. 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 pun a
, b
,c
disebut sebelum sekarang dapat diakses dengan A
, 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.
Hitung
Operator ini hanya bekerja pada nilai integer.
+
Compute b
+ a
(mendorong hasilnya, tetapi tidak membuang salah satu nilai).
-
Hitung b
- a
.
*
Hitung b
* a
.
/
Hitung b
/ a
(pembagian bilangan bulat; putaran menuju infinity negatif).
%
Hitung b
% a
(bilangan bulat modulus; putaran ke arah infinity negatif).
Operator relasional
Operator ini hanya bekerja pada nilai integer.
<
Jika b
kurang dari a
, tekan 1, jika tidak tekan 0.
>
=
Lain-lain
#
Komentar ke akhir baris
- Program harus diakhiri dengan
;
- Semua karakter lain diabaikan.
/usr/bin/cat
) bagaimana dengan Turing-kelengkapan?